With fast.ai, train a simple cnn with images and labels, and then export pkl to local path. Fillanly, use the pkl to recognize an img
To train a simple CNN (Convolutional Neural Network) using the fastai library and then use the trained model to recognize an image, you'll need to follow several steps. Below is a high-level overview of the process:
.pkl
file.Here is a code snippet that demonstrates these steps:
from fastai.vision.all import *
# Step 1: Ensure fastai is installed (you can do this via pip install fastai)
# Step 2: Load your dataset
path = "path/to/your/images"
dls = ImageDataLoaders.from_folder(path, train=".", valid_pct=0.2, item_tfms=Resize(224))
# Step 3: Create a CNN learner
learn = cnn_learner(dls, resnet34, metrics=accuracy)
# Step 4: Train the model
learn.fine_tune(1)
# Step 5: Export the trained model
learn.export('model.pkl')
# Now, your 'model.pkl' file should be available in the same directory as your notebook or script.
# To recognize an image using the exported model:
# Step 6: Load the exported model
learn_inf = load_learner('model.pkl')
# Step 7: Use the model to recognize an image
img = PILImage.create('path/to/your/test/image.jpg')
pred, pred_idx, probs = learn_inf.predict(img)
print(f'Prediction: {pred}; Probability: {probs[pred_idx]:.04f}')
Make sure to replace path/to/your/images
with the actual path to your dataset and path/to/your/test/image.jpg
with the path to the image you want to recognize. The dataset should be structured in a way that fastai can automatically recognize the labels (usually, images for each label/category are kept in separate folders with the folder name as the label).
The cnn_learner
function uses a pre-trained ResNet34 by default, but you can choose a different architecture if you prefer. The fine_tune
method is used to train the model, and you can specify the number of epochs for training.
When you load an image to predict, you should process it in the same way as your training images. The predict
method will return the predicted label, the index of the predicted label, and the probabilities of all classes.
Keep in mind that this is a very simple example for illustration purposes. In practice, you may need to perform additional steps such as data augmentation, choosing a different model architecture, fine-tuning hyperparameters, and evaluating the model's performance more thoroughly.
extract the img recognization process to another file
To separate the image recognition process into another file, you'll need to create two separate Python scripts: one for training and exporting the model, and another for loading the model and predicting new images.
Here's how you can organize the code:
train_export.py
):from fastai.vision.all import *
def train_model(path_to_images, output_path='model.pkl'):
dls = ImageDataLoaders.from_folder(path_to_images, train=".", valid_pct=0.2, item_tfms=Resize(224))
learn = cnn_learner(dls, resnet34, metrics=accuracy)
learn.fine_tune(1)
learn.export(output_path)
if __name__ == '__main__':
path_to_images = "path/to/your/images" # Change this to your dataset path
train_model(path_to_images)
predict.py
):from fastai.vision.all import *
import sys
def load_model(model_path='model.pkl'):
return load_learner(model_path)
def predict_image(image_path, model):
img = PILImage.create(image_path)
pred, pred_idx, probs = model.predict(img)
return pred, probs[pred_idx]
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: python predict.py path/to/model.pkl path/to/image.jpg")
else:
model_path = sys.argv[1]
image_path = sys.argv[2]
model = load_model(model_path)
prediction, probability = predict_image(image_path, model)
print(f'Prediction: {prediction}; Probability: {probability:.04f}')
To run these scripts, you would first execute train_export.py
to train the model and export it to a .pkl
file. Once that's done, you can call predict.py
with the model file and an image to get a prediction.
For example:
python train_export.py
python predict.py model.pkl path/to/your/test/image.jpg
Make sure to replace the placeholder paths with the actual paths to your dataset, model, and test images.
The predict.py
script is designed to take command-line arguments for flexibility. The first argument should be the path to the exported .pkl
file, and the second should be the path to the image you want to recognize. The script will print out the predicted label and its associated probability.
What is the issue with the following code
from fastai.vision.all import *
learn_inf = load_learner('screenshots/model.pkl')
img = PILImage.create('testShots/3.png')
test = learn_inf.predict(img)
print(test)
err:
/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/utils/generic.py:441: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.
_torch_pytree._register_pytree_node(
Traceback (most recent call last):
File "/Users/timqian/Documents/code/timqian/player42/BehavioralCloning/test.py", line 3, in <module>
learn_inf = load_learner('screenshots/model.pkl')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/fastai/learner.py", line 446, in load_learner
try: res = torch.load(fname, map_location=map_loc, pickle_module=pickle_module)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/torch/serialization.py", line 1026, in load
return _load(opened_zipfile,
^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/torch/serialization.py", line 1438, in _load
result = unpickler.load()
^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/torch/serialization.py", line 1431, in find_class
return super().find_class(mod_name, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: Custom classes or functions exported with your `Learner` not available in namespace.\Re-declare/import before loading:
Can't get attribute 'label_func' on <module '__main__' from '/Users/timqian/Documents/code/timqian/player42/BehavioralCloning/test.py'>
The error message you're seeing suggests that there is a custom function or class (in this case, label_func
) that was used when training the Learner
object and was included in the exported .pkl
file, but it is not available in the namespace when you're trying to load the Learner
object.
When you export a Learner
with fastai, it pickles not only the model but also the data preprocessing steps, including any custom code (like a custom label function or any other custom processing function). This means that when you load the Learner
object, you need to make sure that all the custom functions and classes used during training are available in the environment.
To fix this issue, you need to ensure that the function label_func
is defined in the same namespace before you call load_learner
. If label_func
was defined in another script or notebook where the model was originally trained, you need to copy that function definition into the current script.
Here is an example of what you might need to do:
from fastai.vision.all import *
# Define the custom function `label_func` exactly as it was during training
def label_func(x):
# Your custom label function's code
pass
# Now load your learner
learn_inf = load_learner('screenshots/model.pkl')
# Continue with prediction as before
img = PILImage.create('testShots/3.png')
test = learn_inf.predict(img)
print(test)
Make sure to replace the pass
statement with the actual code that defines label_func
. The definition must be exactly the same as it was when you trained and exported the model, including the function name and its parameters.
Once you've included the custom function or class definitions, you should be able to load the Learner
object and use it for predictions without encountering the error.