我找到了examples/image_ocr.py
,似乎是OCR。因此,应该可以为模型提供图像并接收文本。但是,我不知道该怎么做。如何使用新图像提供模型?需要哪种预处理?
安装依赖项:
cairocffi
:sudo apt-get install python-cairocffi
editdistance
:sudo -H pip install editdistance
train
以返回模型并保存经过培训的模型。现在我有model.h5
。下一步是什么?
有关我当前的代码,请参阅https://github.com/MartinThoma/algorithms/tree/master/ML/ocr/keras。我知道如何加载模型(见下文),这似乎工作。问题是我不知道如何将带有文本的图像的新扫描提供给模型。
#!/usr/bin/env python
from keras import backend as K
import keras
from keras.models import load_model
import os
from image_ocr import ctc_lambda_func, create_model, TextImageGenerator
from keras.layers import Lambda
from keras.utils.data_utils import get_file
import scipy.ndimage
import numpy
img_h = 64
img_w = 512
pool_size = 2
words_per_epoch = 16000
val_split = 0.2
val_words = int(words_per_epoch * (val_split))
if K.image_data_format() == 'channels_first':
input_shape = (1, img_w, img_h)
else:
input_shape = (img_w, img_h, 1)
fdir = os.path.dirname(get_file('wordlists.tgz',
origin='http://www.mythic-ai.com/datasets/wordlists.tgz', untar=True))
img_gen = TextImageGenerator(monogram_file=os.path.join(fdir, 'wordlist_mono_clean.txt'),
bigram_file=os.path.join(fdir, 'wordlist_bi_clean.txt'),
minibatch_size=32,
img_w=img_w,
img_h=img_h,
downsample_factor=(pool_size ** 2),
val_split=words_per_epoch - val_words
)
print("Input shape: {}".format(input_shape))
model, _, _ = create_model(input_shape, img_gen, pool_size, img_w, img_h)
model.load_weights("my_model.h5")
x = scipy.ndimage.imread('example.png', mode='L').transpose()
x = x.reshape(x.shape + (1,))
# Does not work
print(model.predict(x))
这给出了
2017-07-05 22:07:58.695665: I tensorflow/core/common_runtime/gpu/gpu_device.cc:996] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX TITAN Black, pci bus id: 0000:01:00.0)
Traceback (most recent call last):
File "eval_example.py", line 45, in <module>
print(model.predict(x))
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1567, in predict
check_batch_axis=False)
File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 106, in _standardize_input_data
'Found: array with shape ' + str(data.shape))
ValueError: The model expects 4 arrays, but only received one array. Found: array with shape (512, 64, 1)
答案 0 :(得分:5)
好吧,我会尽力回答你在这里问到的一切:
如在OCR代码中所评论的,Keras不支持具有多个参数的损耗,因此它计算了lambda层中的NN损失。在这种情况下,这意味着什么?
神经网络可能看起来很混乱,因为它使用4个输入([input_data, labels, input_length, label_length]
)和loss_out
作为输出。除了input_data之外,其他所有信息都仅用于计算损失,这意味着它仅用于训练。我们希望像原始代码的第468行那样:
Model(inputs=input_data, outputs=y_pred).summary()
这意味着“我有一个图像作为输入,请告诉我这里写的是什么”。那么如何实现呢?
1)保持原始训练代码不变,正常进行训练;
2)训练结束后,将此模型Model(inputs=input_data, outputs=y_pred)
保存在.h5文件中,以便随时随地加载;
3)进行预测:如果您查看代码,输入图像将被反转并翻译,因此您可以使用此代码轻松实现:
from scipy.misc import imread, imresize
#use width and height from your neural network here.
def load_for_nn(img_file):
image = imread(img_file, flatten=True)
image = imresize(image,(height, width))
image = image.T
images = np.ones((1,width,height)) #change 1 to any number of images you want to predict, here I just want to predict one
images[0] = image
images = images[:,:,:,np.newaxis]
images /= 255
return images
加载图像后,让我们进行预测:
def predict_image(image_path): #insert the path of your image
image = load_for_nn(image_path) #load from the snippet code
raw_word = model.predict(image) #do the prediction with the neural network
final_word = decode_output(raw_word)[0] #the output of our neural network is only numbers. Use decode_output from image_ocr.py to get the desirable string.
return final_word
这应该足够了。根据我的经验,训练中使用的图像不足以做出良好的预测,我将使用其他数据集发布代码,以便在必要时改进我的结果。
回答相关问题:
这是一种用于改进序列分类的技术。原始论文证明它可以改善发现音频内容的结果。在这种情况下,它是一系列字符。解释有点戏法,但你可以找到一个好的here.
我不确定但您可以查看神经网络中的注意机制。我现在没有任何好的联系,但我知道情况可能就是这样。
OpenCV实现最大稳定的极值区域(称为MSER)。我非常喜欢这个算法的结果,它很快,在我需要时对我来说足够好。
正如我之前所说,我将很快发布一个代码。我会在使用存储库时编辑问题,但我相信这里的信息足以让示例运行。
答案 1 :(得分:4)
在这里,您创建了一个需要4个输入的模型:
model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)
另一方面,您的预测尝试只是加载图像 因此消息:该模型需要4个数组,但只接收一个数组
从您的代码中,必要的输入是:
input_data = Input(name='the_input', shape=input_shape, dtype='float32')
labels = Input(name='the_labels', shape=[img_gen.absolute_max_string_len],dtype='float32')
input_length = Input(name='input_length', shape=[1], dtype='int64')
label_length = Input(name='label_length', shape=[1], dtype='int64')
原始代码和您的培训工作因为他们正在使用TextImageGenerator
。该发生器可以为您提供模型的四个必要输入。
所以,你要做的就是预测使用发电机。由于您拥有使用生成器进行训练的fit_generator()
方法,因此您还可以使用predict_generator()方法来预测生成器。
现在,要获得完整的答案和解决方案,我必须研究您的发电机,看看它是如何工作的(这需要一些时间)。但是现在你知道要做什么,你可能会想出来。
您可以按原样使用生成器,也可以预测大量数据,或者您可以尝试复制一个只生成一个或几个具有必要标签,长度和标签长度的图像的生成器。
或者,如果可能的话,只需手动创建剩余的3个数组,但要确保它们具有相同的形状(第一个除外,即批量大小)作为生成器输出。
但是,你必须断言的一件事是:有4个阵列与发电机输出的形状相同,除了第一个维度。
答案 2 :(得分:2)
现在我有一个model.h5。下一步是什么?
首先我应该评论model.h5
包含网络的权重,如果您希望保存网络的架构,那么您应该保存它像json
这样的例子:
model_json = model_json = model.to_json()
with open("model_arch.json", "w") as json_file:
json_file.write(model_json)
现在,一旦掌握了模型及其权重,您可以按照以下要求加载它们:
json_file = open('model_arch.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# load weights into new model
# if you already have a loaded model and dont need to save start from here
loaded_model.load_weights("model.h5")
# compile loaded model with certain specifications
sgd = SGD(lr=0.01)
loaded_model.compile(loss="binary_crossentropy", optimizer=sgd, metrics=["accuracy"])
然后,使用loaded_module
,您可以继续预测某些输入的分类,如下所示:
prediction = loaded_model.predict(some_input, batch_size=20, verbose=0)
将返回该输入的分类。
关于附带问题:
在接下来的内容中,我们将引用来标记 分段数据序列为 时间分类 (Kadous,2002),以及我们对此用途的RNN的使用 摆姿势 联结主义时间分类 (的 CTC 强>)。
Keras
示例,我们可以从git看到:此示例使用卷积堆栈,后跟循环堆栈 和CTC logloss功能,以执行光学字符识别 生成的文本图像。
您可以查看与您正在做的事情相关的this教程以及他们在何处解释有关卷积神经网络的更多信息。
编辑:您收到的错误是因为我们可以看到来自keras docs的更多参数而不是1:
predict(self, x, batch_size=32, verbose=0)
引发ValueError:如果提供的输入数据与模型的预期不匹配,或者有状态模型收到的批量大小不是倍数的样本。
答案 3 :(得分:-1)
嗨,您可以同样查看我的github repo。您需要针对要进行ocr的图像类型训练模型。
# USE GOOGLE COLAB
import matplotlib.pyplot as plt
import keras_ocr
images = [keras_ocr.tools.read("/content/sample_data/IMG_20200224_113657.jpg")] #Image path
pipeline = keras_ocr.pipeline.Pipeline()
prediction = pipeline.recognize(images)
x_max = 0
temp_str = ""
myfile = open("/content/sample_data/my_file.txt", "a+")#Text File Path to save text
for i in prediction[0]:
x_max_local = i[1][:, 0].max()
if x_max_local > x_max:
x_max = x_max_local
temp_str = temp_str + " " + i[0].ljust(15)
else:
x_max = 0
temp_str = temp_str + "\n"
myfile.write(temp_str)
print(temp_str)
temp_str = ""
myfile.close()