简体   繁体   中英

How to train new digits handwriting into exist keras model?

I'm having an existing model that trained to recognize handwritten digits. Then I have a new sample digit to train more into that model. Is there any way to do this?

  import os
  import cv2 as cv
  import numpy as np
  import matplotlib.pyplot as plt
  import tensorflow as tf

  ### train model ###
  mnist = tf.keras.datasets.mnist
  (x_train, y_train), (x_test, y_test) = mnist.load_data()
  x_train = x_train/255
  x_test = x_test/255

  model = tf.keras.models.Sequential()
  model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
  model.add(tf.keras.layers.Dense(units=128,activation=tf.nn.relu))
  model.add(tf.keras.layers.Dense(units=10,activation=tf.nn.softmax))

  model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])

  model.fit(x_train, y_train, epochs=5)
  model.save('traineddata.model')

My new sample is number 1 like this: 在此处输入图像描述

You could load image, convert to grayscale, resize to (28,28)
and convert to train array with one example, and use it with fit()

x_example = cv2.imread('image.png')
x_example = cv2.cvtColor(x_example, cv2.COLOR_BGR2GRAY)
x_example = cv2.resize(x_example, (28, 28))

y_example = 1

x_data = np.array( [ x_example ] )  # it has to be array with shape (1, 28, 28) instead of (28, 28)
y_data = np.array( [ y_example ] )  # it has to be array with shape (1, 1) instead of (1,)

model.fit(x_data, y_data, epochs=5)

but it doesn't give good prediction for epochs=5 .
For epochs=10 it gives correct prediction for this image but I didn't check if it still gives correct predictions for other images.

Maybe it would be better to add image to x_train , y_train and retrain all again.

x_data = np.append(x_train, [x_example], axis=0)
y_data = np.append(y_train, y_example)

model.fit(x_data, y_data, epochs=5)

It can be like in real life - when you learn new element then you better remeber it then older elements. When you learn again all elements with new element then you refresh all information and you remeber all of them.


Minimal working code which I used for test.

import warnings

warnings.filterwarnings('ignore')  # hide/supress warnings

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

### train model ###

def build():
    print('-'*50)
    print('# Building model ')
    print('-'*50)
    
    model = tf.keras.models.Sequential()
    model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
    model.add(tf.keras.layers.Dense(units=128, activation=tf.nn.relu))
    model.add(tf.keras.layers.Dense(units=10, activation=tf.nn.softmax))
    
    model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])

    return model
    
def train(model, x_train, y_train, epochs=5):
    print('-'*50)
    print('# Training model')
    print('-'*50)
    
    model.fit(x_train, y_train, epochs=epochs)

def save(model):
    print('-'*50)
    print('# Saving model')
    print('-'*50)

    model.save('traineddata.model')

def load():
    print('-'*50)
    print('# Loading model')
    print('-'*50)
    
    return tf.keras.models.load_model('traineddata.model')

def test_one(model, x_example, y_example):
    print('-'*50)
    print('# Testing one element')
    print('-'*50)
    
    # create array with one or more images
    x_data = np.array( [ x_example ] )
    y_data = np.array( [ y_example ] )

    print('x_data shape:', x_data.shape)
    print('y_data shape:', y_data.shape)
    print(' expected:', y_data)

    # get list with one or more predictions
    y_results = model.predict(x_data)

    print('predicted:', y_results.argmax(axis=1))

def retrain_one(model, x_example, y_example, epochs=5):
    print('-'*50)
    print('# Retraining one element')
    print('-'*50)

    # create array with one or more images
    x_data = np.array( [ x_example ] )
    y_data = np.array( [ y_example ] )

    print('x_data shape:', x_data.shape)
    print('y_data shape:', y_data.shape)
    print('y_data:', y_data)

    model.fit(x_data, y_data, epochs=epochs)

def retrain_all(model, x_train, y_train, x_example, y_example, epochs=5):
    print('-'*50)
    print('# Retraining all elements')
    print('-'*50)

    # create array with all images
    x_data = np.append(x_train, [x_example], axis=0)
    y_data = np.append(y_train, y_example)

    print('x_data shape:', x_data.shape)
    print('y_data shape:', y_data.shape)
    print('y_data:', y_data)

    model.fit(x_data, y_data, epochs=epochs)

# --- main ---

# - load train/test images -

print('>>> Loading train/test data ...')
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

x_train = x_train/255
x_test = x_test/255

# - train + save or load -

if not os.path.exists('traineddata.model'):
    print('>>> Building model ...')
    model = build()

    print('>>> Training model ...')
    train(model, x_train, y_train)

    print('>>> Saving model ...')
    save(model)
else:
    print('>>> Loading model ...')
    model = load()

#print(' - test on single example - ')
#index = 0
#test_one(model, x_train[index], y_train[index])

print(' - image - ')

x_example = cv2.imread('image.png')
x_example = cv2.cvtColor(x_example, cv2.COLOR_BGR2GRAY)
x_example = cv2.resize(x_example, (28, 28))

y_example = 1

print('>>> Predicting without training')

test_one(model, x_example, y_example)

print('>>> Predicting with training one element (epochs=10)')

retrain_one(model, x_example, y_example, epochs=10)  # epochs=5 epochs=7
test_one(model, x_example, y_example)

print('>>> Predicting with retraining all elements')

retrain_all(model, x_train, y_train, x_example, y_example)
test_one(model, x_example, y_example)

#print('>>> Saving new model')
#model.save('traineddata.model')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM