見つけました 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)
さて、私はあなたがここで尋ねたすべてに答えようとします:
OCRコードでコメントされているように、Kerasは複数のパラメーターでの損失をサポートしていないため、ラムダレイヤーの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
_
これで十分でしょう。私の経験から、トレーニングで使用される画像は良い予測をするのに十分ではありません。必要に応じて後で結果を改善する他のデータセットを使用してコードをリリースします。
関連する質問への回答:
これは、シーケンス分類を改善するために使用される手法です。オリジナルの論文は、音声で言われていることを発見することで結果を改善することを証明しています。この場合、文字のシーケンスです。説明はちょっとしたトリックですが、良いものを見つけることができます こちら
よくわかりませんが、ニューラルネットワークのアテンションメカニズムをご覧ください。現在、良いリンクはありませんが、そうなる可能性があります。
OpenCVは、Maximally Stable Extremal Regions(MSER)を実装しています。私はこのアルゴリズムの結果が本当に好きです。それは高速で、必要なときに十分でした。
前にも言ったように、すぐにコードをリリースします。リポジトリを使用して質問を編集しますが、ここでの情報でサンプルを実行することができます。
ここでは、4つの入力が必要なモデルを作成しました。
_model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)
_
一方、予測の試みは、画像だけをロードすることです。
したがって、メッセージ:モデルは4つのアレイを想定していますが、1つのアレイのみを受け取りました
コードから、必要な入力は次のとおりです。
_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
を使用しているため機能します。このジェネレーターは、モデルに必要な4つの入力を提供します。
したがって、ジェネレーターを使用して予測する必要があります。ジェネレーターでトレーニングするfit_generator()
メソッドがあるので、ジェネレーターで予測する predict_generator() メソッドもあります。
さて、完全な答えと解決策のために、私はあなたの発電機を研究し、それがどのように機能するかを見る必要があります(これには時間がかかります)。しかし、今、あなたは何をすべきかを知っています、あなたはおそらくそれを理解することができます。
ジェネレータをそのまま使用して、おそらく膨大な量のデータを予測するか、必要なラベル、長さ、ラベルの長さを備えた1つまたはいくつかの画像を生成するジェネレータを複製することができます。
または、可能であれば、残りの3つの配列を手動で作成しますが、ジェネレーターの出力と同じ形状(バッチサイズである最初のものを除く)であることを確認します。
ただし、アサートする必要がある1つのことは、最初の次元を除き、ジェネレーター出力と同じ形状の4つの配列があることです。
これでmodel.h5ができました。次は何ですか?
最初に、model.h5
にネットワークのweightsが含まれていることをコメントする必要があります。ネットワークのarchitectureも保存する場合は、 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 :この例では、convolutionalスタックに続いて再帰スタックとCTCログロス関数を使用して、生成されたテキスト画像の光学文字認識を実行します。
this あなたがやっていることに関連するチュートリアルと、畳み込みニューラルネットワークについてさらに説明している場所を確認できます。
編集:取得しているエラーは、kerasから1ではなく、より多くのパラメータが予想されるためです docs :
predict(self, x, batch_size=32, verbose=0)
ValueErrorを発生させます:提供された入力データとモデルの期待値が一致しない場合、またはステートフルモデルがバッチサイズの倍数ではないサンプルの数を受け取る場合。