我如何使用Keras OCR示例?

Mar*_*oma 20 python ocr keras

我找到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.我知道如何加载模型(见下文),这似乎工作.问题是我不知道如何将带有文本的图像的新扫描提供给模型.

相关的问题

  • 什么是CTC?联结主义时间分类
  • 是否有可靠地检测文档旋转的算法?
  • 是否存在可靠地检测线/文本块/表/图像的算法(从而进行合理的分割)?我想平滑和直线直方图的边缘检测已经相当不错了吗?

我尝试了什么

#!/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))
Run Code Online (Sandbox Code Playgroud)

这给了

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)
Run Code Online (Sandbox Code Playgroud)

Cla*_*dio 7

好吧,我会尽力回答您在这里提出的所有问题:

如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()
Run Code Online (Sandbox Code Playgroud)

意思是“我有图像作为输入,请告诉我这里写的是什么”。那么如何实现呢?

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
Run Code Online (Sandbox Code Playgroud)

加载图像后,让我们进行预测:

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
Run Code Online (Sandbox Code Playgroud)

这应该足够了。根据我的经验,训练中使用的图像不足以做出正确的预测,我将使用其他数据集发布代码,以在需要时改善结果。

回答相关问题:

这是用于改善序列分类的技术。原始论文证明,它可以改善发现音频中所讲内容的结果。在这种情况下,它是一个字符序列。解释有些技巧,但是您可以在这里找到一个很好的解释

  • 是否有可以可靠检测文件旋转的算法?

我不确定,但是您可以看一下神经网络中的注意力机制。我现在没有任何好的链接,但我知道可能是这种情况。

  • 是否存在可以可靠地检测行/文本块/表格/图像的算法(因此可以进行合理的分割)?我想用平滑和逐行直方图进行边缘检测已经相当有效了吗?

OpenCV实现最大稳定的末梢区域(称为MSER)。我真的很喜欢这种算法的结果,它的速度很快,并且在需要时对我来说足够好。

如前所述,我将很快发布代码。这样做时,我将使用存储库来编辑问题,但是我相信这里的信息足以使示例运行。


Dar*_*nus 3

现在我有一个 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)
Run Code Online (Sandbox Code Playgroud)

现在,一旦您有了模型及其权重,您就可以通过执行以下操作按需加载它们:

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"])
Run Code Online (Sandbox Code Playgroud)

然后,loaded_module您可以继续预测某些输入的分类,如下所示:

prediction = loaded_model.predict(some_input, batch_size=20, verbose=0)
Run Code Online (Sandbox Code Playgroud)

这将返回该输入的分类。

关于附带问题:

  1. CTC 似乎是他们在您引用的论文中定义的一个术语,摘录如下:

在下文中,我们将标记未分段数据序列的任务称为时间分类(Kadous,2002),并将为此目的使用 RNN 称为联结主义时间分类(CTC)。

  1. 为了补偿文档、图像或类似文件的旋转,您可以通过应用此类转换从当前的数据生成更多数据(请查看这篇博客文章,其中解释了一种方法),或者您可以使用卷积神经网络网络方法,这实际上也是您正在使用的示例的作用,正如我们从gitKeras中看到的那样:

此示例使用卷积堆栈,后跟循环堆栈和 CTC 对数损失函数来对生成的文本图像执行光学字符识别。

您可以查看与您正在做的事情相关的本教程,其中还解释了有关卷积神经网络的更多信息。

  1. 嗯,这是一个广泛的问题,但要检测线条,您可以使用霍夫线变换,或者Canny 边缘检测也可能是不错的选择。

编辑:您收到的错误是因为需要更多参数而不是 1 个,从 keras文档中我们可以看到:

predict(self, x, batch_size=32, verbose=0)
Run Code Online (Sandbox Code Playgroud)

引发 ValueError:如果提供的输入数据与模型的期望不匹配,或者有状态模型收到的样本数量不是批量大小的倍数。