Get Cooking with ChatGPT

ChatGPT from OpenAI has been getting a lot of publicity recently. If you haven’t heard of it, ChatGPT is an acronym for Chat Generative Pre-trained Transformer. What does that mean? It’s a chatbot that’s been tuned through reinforcement and supervised learning. There has been much discussion about the accuracy and usability of ChatGPT.

ChatGPT Models

ChatGPT currently offers three different models for response generation. They have different capabilities and come with different pricing. The models are:

  • GPT-3, for understanding and generating natural language.
  • Codex, for understanding and generating software code.
  • Content filter, for determining whether text may be sensitive or unsafe

Being in the software industry, the Codex model is intriguing, but I have yet to see examples of auto-generated code that does exactly what I’m trying to accomplish. Therefore, having previous experience in the culinary industry I thought it would be interesting to try ChatGPT in that arena using the GPT-3 model. Let’s see what sort of recipes ChatGPT can generate and how true to the classic recipes they are.

There are four different model options available when using the overall GPT-3 model: text-ada-001, text-babbage-001, text-curie-001, and text-davinci-003. The models go along a speed/cost scale of fast & inexpensive with text-ada-001 to the most capable but slower & more expensive text-davinci-003. While fine-tuning these models is an option, it goes beyond the scope of this post. With that in mind, let’s look at what these different models can generate for us “out of the box.”

The Recipe

In classical French cuisine, there are five mother sauces on which other sauces are based. To test out ChatGPT’s recipe generation, let’s look at one of these classic sauces: Béchamel. Béchamel is a simple sauce, from a classic ingredient standpoint, in that it contains butter, all-purpose flour, milk, salt, and pepper.

Let’s write a brief Python application that we’ll use to access the OpenAI API and see what responses we get from ChatGPT.

First, we’ll need to get an account with OpenAI and an API Key. As a best practice to keep your API Key safe, using an API Vault, such as Pangea’s Vault is a great idea. At a bare minimum, assign it to an environment variable so you can access in your application but not need to save the key in your code file.

Second, we’ll need to install OpenAI using a package management tool such as pip or pipenv. I prefer pipenv, so running the following command will get that installed:

pipenv install openai

Now, in a Python file, chatgpt-python.py, we’ll make a “How do I make bechamel sauce?” request to OpenAI using the four different GPT-3 models:

import openai
import os

openai.api_key = os.environ['OPENAPI_APIKEY']

# Choose the model engine
model_engines = ["text-ada-001", "text-babbage-001", "text-curie-001", "text-davinci-003"]

# The question passed into the API
prompt = "How do I make bechamel sauce?"

for model_engine in model_engines:

     # Response generation
     generator = openai.Completion.create(
          engine=model_engine,  # (REQUIRED) - the model to use
          prompt=prompt,  # (OPTIONAL) - the prompt that's passed to the API
          max_tokens=1024, # (OPTIONAL) - the max # of tokens to generate
          n=1,  # (OPTIONAL) - how many completions to generate
          stop=None,  # (OPTIONAL) - stop word string or array.
          temperature=0.5.  # (OPTIONAL) - the coherency of the generated response. Number between 0 and 2
)

     generated_response = generator.choices[0].text
     print("Response for " + model_engine + ": ")
     print(generated_response)

In the response generator, we have a few options, and we’re defining the model engine, passing in the prompt, defining the number of tokens used from the API (default is 16), and how many completions are generated for each prompt (default is 1), any stop sequences we want to define to stop further token generation, and the temperature of the response.

What is the temperature? It defines the randomness (coherency) of the generated response. Lower numbers here make the responses more focused and higher numbers generate more random output. We’ll explore this in a bit. For now, here are the responses I got from the above script. Remember that we’re looking for an answer to the question of “How do I make béchamel sauce?”

text-ada-001 (.50 second response)

There is no one definitive way to make bechamel sauce. However, most likely you will need to use grated cheese, milk, and butter.

Hmmm, that doesn’t really seem helpful and while there are sauces based on a bechamel that include cheese the base sauce doesn’t.

text-babbage-001 (0.61 second response)

Place a pot of water on the stove to boil. Add a cup of sugar and cook until the sugar has dissolved. Add a cup of milk and cook until the milk has boiled off. Pour the sauce into a saucepan and stir in the bechamel sauce ingredients. Cook over low heat until thickened.

Again, not spectacularly useful, for classic béchamel with sugar being mentioned. Also, what is a “pot of water” exactly? 1 cup, 1 quart, 5 gallons? I’m not sure what “until the milk has boiled off” means in this context either. And then, a very cyclical instruction for how to make bechamel sauce: “stir in the bechamel sauce ingredients.”

text-curie-001 (.84 second response)

Bechamel sauce is a simple sauce made from milk and flour. Heat milk in a saucepan over medium heat until it starts to simmer. Whisk in flour until a smooth paste forms. Cook, stirring constantly, until the sauce thickens. Serve hot.

Getting closer here, but still not quite there. Using straight flour to thicken milk doesn’t create a great flavor. However, even without measurements, you could generate something here, right? Even with 100 gallons of milk being heated to a simmer you know that you must add in enough flour until a “smooth paste forms.” Still, far from a classical béchamel sauce.

text-davinci-003 (7.3 second response)

Bechamel sauce is a classic French sauce made from a roux of butter and flour, and a liquid, usually milk. Here is a basic recipe:

Ingredients:

-3 tablespoons butter
-3 tablespoons all-purpose flour
-2 cups milk
-Salt and freshly ground pepper
-Pinch of ground nutmeg

Instructions:

1. Melt the butter in a saucepan over medium heat.
2. Add the flour and whisk until the mixture is smooth and bubbling.
3. Gradually whisk in the milk, whisking constantly to avoid lumps.
4. Continue to whisk until the sauce thickens, about 5 minutes.
5. Season with salt, pepper, and nutmeg.
6. Serve warm.

This is a recipe that one could work with. I’d have a few nit-picks with the instructions, but overall, it makes sense. Personally, I wouldn’t add the nutmeg and it isn’t explicitly classical, but I’ve seen it done.

Temperature Adjustment

As mentioned earlier, the temperature parameter adjusts the “coherency” of the generated output. You can set that parameter to a number between 0 and 2. Recall that the above script ran with a temperature parameter of 0.5. The output was, while not always helpful, at least coherent.

The output from the text-davinci-003 model was useful. Let’s see what happens if we alter the temperature parameter value.

temperature=1.75

Bechamel is one of the staples in employing tha classic “mother tastes” that understands fundamental techniques, which are included bases like Bechamel felt se as Milk, simple sugars /mutable faster blend together all seeds again serve holes along veggies traditional

That’s just the introduction, the rest of the “recipe” isn’t much better…

To make béchamel classic:

1 MELT 2 tablespoons worthwhile normal core puns international info and work users tub back stainless stre ‘tub fully restricted sized documents allowed uses principle-friendly views data

… and it goes on but becomes less coherent.

temperature=0.2

Let’s go in the other direction and reduce the temperature parameter value. Here are the results:

Bechamel sauce is a classic French white sauce made with butter, flour, and milk.

Ingredients:

– 2 tablespoons butter
– 2 tablespoons all-purpose flour
– 2 cups milk
– Salt and pepper to taste

Instructions:

1. In a medium saucepan, melt the butter over medium heat.
2. Add the flour and whisk until the mixture is smooth and bubbly.
3. Gradually add the milk, whisking constantly until the mixture is smooth.
4. Bring the mixture to a boil, then reduce the heat and simmer for 5 minutes, stirring occasionally.
5. Season with salt and pepper to taste.
6. Serve over your favorite dish. Enjoy!

Another great béchamel recipe, and this time without nutmeg!

I don’t believe you. You’re an impasta!

As we’ve seen using OpenAI and ChatGPT can have some interesting results. You might wind up with some imposter recipes or you might wind up with some winners. That is true overall, in my opinion, for AI-generated content now though. Could you build an entire application strictly based on results from ChatGPT? Perhaps. Individual results may vary though.

As the models get better, get more use, and “learn” more, things might change. And recipe creation is just one small example of this technology. We see folks attempting to use it in areas such as courtrooms, health care, insurance, and more. In comparison, culinary uses seem safe. Just based on the varying results of a béchamel sauce recipe, I think we have a ways to go with this technology.

Facebooktwitterredditlinkedinmail

Flask Blood Glucose Tracker

My oldest daughter was diagnosed with Type 1 Diabetes at the age of two. Technology has come a long way in terms of tracking blood sugar levels, but I thought I would start a Python web application to do so. I’ll be using the Flask web framework for the project and, since I’m not a marketing or product naming genius, will call the project Flask Blood Glucose Tracker. I’m certainly open to other, more catchy, names.

This is somewhat of a different post for me, in that I’ll be walking through the generation of an actual application. The application will mostly be a minimal viable product (MVP) though. It should, however, be a good tutorial on how to integrate some concepts and technologies together. As such, in this first post, I’ll cover some of the project specifications and features that I’d like to include and work on implementing them in future posts.

Application for Diabetes

Diabetics have to check their blood glucose levels frequently, typically using a blood sugar monitor. These checks involve getting a small portion of blood from a finger (or arm) prick and having the monitor test it. It then returns a measurement of the amount of glucose in the blood as a number of milligrams per deciliter (mG/dL). These readings then will be the numbers we want to record in our application.

It is also important to know if the reading is taken before or after eating and the time of day the reading was taken. Therefore, the application will need to accommodate for that as well. The readings themselves, along with the time of day and relation to meal time are all factors into the amount of insulin needs to be injected.

Throughout this, and subsequent posts, I will do my best to explain diabetes-specific terms in as user-friendly of a way as possible. I am basing much of the numbers that I use, ranges of “good and bad”, etc. on managing my daughter’s diabetes over the last 14 years and the countless doctor appointments I’ve attended. As a disclaimer, I am not a medical professional. Please check with your physician about specifics with diabetes. There is a Diabetes For Dummies book which provides a decent overview as well.

Flask Blood Glucose Tracker Application Features

There are already a lot of excellent products on the market for keeping track of one’s blood sugar levels. With that in mind, this application is going to be fairly simple to start. I would like to build it with growth in mind, however, so building a REST API into the project seems like a good idea. My basic feature list to start with is:

  • Register for the BGT site, with email confirmation.
  • Login/Logout and based on role have different access.
    • Patient to access and edit my own data.
    • Physician to get a list of all current patient records.
    • Administrator for site maintenance.
  • Input blood sugar levels with date and time of reading and indication of before or after a meal or snack.
  • Display the data in a table with averages.
  • Display the data in a chart or visual format.
  • Typical CRUD operations for the data
  • REST API to expose patient blood sugars in a secure fashion
  • Data is stored in the cloud for accessibility and ease of database maintenance.

For the reporting features highlighting high and low blood sugar levels in the report would be helpful. Since what is “good” and “bad” can change for each individual, I’ll include a field for each individual to set that.

Application Stack

I have already mentioned that this application will be built with Flask. For the data store, I will use MongoDB. To keep in line with the feature request of storing data in the cloud, MongoDB offers a Database as a Service (DBaaS) called Atlas.

I haven’t quite figured out yet where I’ll ultimately host this application, perhaps Heroku? Or maybe on my own server.

Application Libraries

When it comes to libraries, there are a lot of choices. Here’s what I’ll be using, which will also be included in a requirements.txt file.

  • Flask version 0.12.2
  • Flask-Login, 0.4.0
  • Flask-PyMongo, 0.5.1
  • Bokeh, 0.12.6
  • Jinja2, 2.9.6
  • pandas, 0.20.2

There are other libraries that will but used as well, but those are the main ones of interest.

I’m also more of a fan of Zurb Foundation than Twitter Bootstrap, so I’ll be using that for styling.

Pages and Routes

Web Pages

To start with we need a way for a user to log in, enter their personal data, enter a new blood sugar record, edit their record, and view their information in both a tabular format and then in a chart format.

We’ll need the following pages, at least to start.

  • Index
  • Registration
  • Login/Logout Page
  • Profile page, login required
  • Records page (create, read, update, delete), login required
  • Chart page, login required

For a Physician we would want to be able to:

  • Display all of their patients, login required

For an Administrator, we want to be able to

  • Have the ability to manage users (patients & physicians) but not be able to see patient medical data.
REST API Routes

From the API I want to expose the ability to securely read and write (GET and POST) data to a patient’s record. This will make it easier to, for example, write a mobile application to connect to our data. Or, with the advances in blood sugar monitors, perhaps automatically update our application with readings from a device.

Document Model

Since I will be using MongoDB to store data for this application, I’ll be leveraging the document model. This offers a lot of flexibility in how data is stored, among other benefits. I would encourage you to read my blog post on the document model if you are not familiar with it.

To start with, the basic data we want to capture and model will be as follows:

BGT Sample Document
Sample Patient Record document

In looking at this sample document, the groups field will keep track of values such as patientphysician, and admin. I have chosen to implement the postal_code and MRN values as strings instead of integers to accommodate alpha-numeric values.

Through the course of developing this application, we will see the flexibility of the document model in action. We’ll see how we can utilize some of the features from MongoDB’s aggregation pipeline to handle our data processing as well.

Wrap Up

I have outlined a nice project here which will utilize several different bits of programming. In the next few posts then, I’ll cover how to implement all of these features into an MVP application. I would definitely enjoy receiving feedback, so please leave comments below.

 


Follow me on Twitter @kenwalger to get the latest updates on my postings.Facebooktwitterredditlinkedinmail