기계 학습×웹 앱 진단: 다층 퍼셉트론으로 CAPTCHA를 인식한다(Chainer편)
이번에는 「 Chainer 」를 사용해 같은 것을 해 본다.
덧붙여 「scikit-neuralnetwork」에서도 다층 퍼셉트론을 실장할 수 있지만, 이 검증은 또 기회로 한다.
아젠다
0. 구현 코드
1. 해보자
2. 정리
3. 참고 문헌
0. 구현 코드
아래 하나의 파이썬 코드 만 사용.
전회에 비해 매우 코드량이 적어지고 있다.
mlp.py#!/usr/bin/env python
#coding:utf-8
import os
import gzip, pickle
import pylab
import numpy as np
from chainer import Variable, FunctionSet, optimizers
import chainer.functions as F
# 学習データのロード
def train_data_read(file_path):
# 学習データ(MNISTの手書き文字)のロード
f = gzip.open(file_path, 'rb')
train, valid, test = pickle.load(f)
f.close()
return (train[0], train[1], train[0].shape[0])
# ニューラルネットワーク(多層パーセプトロン)の処理
def forward(x_data, y_data, train=True):
x = Variable(x_data)
t = Variable(y_data)
# 活性化関数に正規化線形関数(ReLU)を使用
# 汎化性能向上のためにドロップアウトを使用
h1 = F.dropout(F.relu(model.l1(x)), train=train)
h2 = F.dropout(F.relu(model.l2(h1)), train=train)
y = model.l3(h2)
# 誤差関数に交差エントロピーを使用
return F.softmax_cross_entropy(y, t)
# データの予測
def predict(x_test):
x = Variable(x_test)
# 活性化関数に正規化線形関数(ReLU)を使用
# 汎化性能向上のためにドロップアウトを使用
h1 = F.dropout(F.relu(model.l1(x)))
h2 = F.dropout(F.relu(model.l2(h1)))
y = model.l3(h2)
return np.argmax(y.data)
if __name__ == "__main__":
# 識別対象のCAPTCHA画像が格納されているファイルパスを定義
captcha_path = 'C:\MNIST\captcha\captcha0'
# 訓練用データ(MNIST)のファイルパスを定義
train_data_path = os.path.join('C:\\MNIST', 'mnist.pkl.gz')
# 正解ラベルの定義(結果表示用)
answerLabel = [0, 1, 4, 6, 7, 9]
# 予測対象データ(CAPTCHA画像)の取得
# 画像データを784次元のベクトルに変換
# RGB毎の配列からR要素のみを抽出(次元削減)
img_captcha = []
analize_data = []
captcha_files = os.listdir(captcha_path)
for file in captcha_files:
img_captcha = pylab.imread(os.path.join(captcha_path,file))
img_captcha_r = img_captcha[:, :, 0]
#img_captcha_r = img_captcha[:, :]
img_captcha_Array = np.asarray(img_captcha_r)
d_captcha = img_captcha_Array.shape[0] * img_captcha_Array.shape[1]
img_captcha_wide = img_captcha_Array.reshape(1, d_captcha)
analize_data.append(img_captcha_wide)
# 訓練データの取得
x_train, y_train, length = train_data_read(train_data_path)
x_train = x_train.astype(np.float32)
y_train = y_train.astype(np.int32)
# ニューラルネットワークの構築
# 入力層=784(28*28)、中間層=300、出力層=10(0~9)
model = FunctionSet(l1=F.Linear(784, 300),
l2=F.Linear(300, 300),
l3=F.Linear(300, 10))
# 確率的勾配降下法(SGD)で学習する際のバッチサイズ
# 10~100程度とすることが多いが、最も結果が良かった100とした。
batchsize = 100
# 学習の繰り返し回数
# 5回の学習で精度が95%を超えたため、5回とした。
learning_loop = 5
# SGDの設定
optimizer = optimizers.Adam()
optimizer.setup(model.collect_parameters())
# 学習
N = 50000
for epoch in range(1, learning_loop+1):
# 学習データの順番をランダムにする
perm = np.random.permutation(N)
# 0〜Nまでのデータをバッチサイズに区切って学習する
for i in range(0, N, batchsize):
x_batch = x_train[perm[i:i+batchsize]]
y_batch = y_train[perm[i:i+batchsize]]
# 重みの初期化
optimizer.zero_grads()
# フィードフォワードさせて誤差を算出
error = forward(x_batch, y_batch)
# バックプロパゲーションで勾配を算出
error.backward()
# 重みを更新
optimizer.update()
# CAPTCHAデータの予測
ok = 0
for i in range(len(analize_data)):
# 認識対象データを1個ずつ読み込む
x = analize_data[i].astype(np.float32)
# 認識対象の正解データを1個ずつ読み込む
y = answerLabel[i]
# CAPTCHAデータの予測
answer = predict(x)
# 予測値と正解データを標準出力する
print("No.{0:d} : predict => {1:d} , answer = > {2:d}".format(i, answer, int(y)))
# 予測値と正解データが一致している場合、ok(正解)を1インクリメントする
if int(y) == answer:
ok += 1
# ok(正解)の数と認識対象データ数を基に正解率を標準出力する
print("{0:05d} / {1:05d} = {2:3.2f}%".format(ok, len(analize_data), 100*ok/len(analize_data)))
피드 포워드나 백프로파게이션, 확률적 그라디언트 강하법(SGD)이나 드롭아웃 등의 테크닉이 매우 간이한 코드로 실현할 수 있다.
얼마나 멋진 도서관이야!
1. 해보자
조속히 이것을 사용해 CAPTCHA의 인식을 해 본다.
우선은 첫 번째 지금부터.
첫 번째 예측 결과No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 4 , answer = > 4
No.3 : predict => 6 , answer = > 6
No.4 : predict => 7 , answer = > 7
No.5 : predict => 9 , answer = > 9
00006 / 00006 = 100.00%
정답률은 100%.
이것은 지난번과 다르지 않다.
다음은 두 번째 이것이다.
두 번째 예측 결과No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 6 , answer = > 4
No.3 : predict => 8 , answer = > 6
No.4 : predict => 8 , answer = > 7
No.5 : predict => 9 , answer = > 9
00003 / 00006 = 50.00%
정답률은 50%.
전회는 33.33%였으므로, 개선되고 있는 것을 알 수 있다.
2. 정리
Chainer를 사용하여 숫자 이미지의 인식을 시도했습니다.
전회보다 정답률이 개선되고 있다.
학습 횟수를 늘리면 더욱 정답률은 올라갈 것으로 보이지만, 전회도 쓴 것처럼 학습 데이터를 궁리하지 않는 것은 근본 해결이 되지 않는다.
오히려 이번 검증에서 특필해야 할 것은, 매우 간이한 코드로 다층 퍼셉트론을 실장할 수 있어 게다가 정답률을 개선할 수 있었을 것이다.
앞으로 Chainer와 Deap을 사용하여 Neuroevolution을 구현하고 웹 응용 프로그램의 자동 크롤러를 개발하려고합니다.
3. 참고 문헌
아래 하나의 파이썬 코드 만 사용.
전회에 비해 매우 코드량이 적어지고 있다.
mlp.py
#!/usr/bin/env python
#coding:utf-8
import os
import gzip, pickle
import pylab
import numpy as np
from chainer import Variable, FunctionSet, optimizers
import chainer.functions as F
# 学習データのロード
def train_data_read(file_path):
# 学習データ(MNISTの手書き文字)のロード
f = gzip.open(file_path, 'rb')
train, valid, test = pickle.load(f)
f.close()
return (train[0], train[1], train[0].shape[0])
# ニューラルネットワーク(多層パーセプトロン)の処理
def forward(x_data, y_data, train=True):
x = Variable(x_data)
t = Variable(y_data)
# 活性化関数に正規化線形関数(ReLU)を使用
# 汎化性能向上のためにドロップアウトを使用
h1 = F.dropout(F.relu(model.l1(x)), train=train)
h2 = F.dropout(F.relu(model.l2(h1)), train=train)
y = model.l3(h2)
# 誤差関数に交差エントロピーを使用
return F.softmax_cross_entropy(y, t)
# データの予測
def predict(x_test):
x = Variable(x_test)
# 活性化関数に正規化線形関数(ReLU)を使用
# 汎化性能向上のためにドロップアウトを使用
h1 = F.dropout(F.relu(model.l1(x)))
h2 = F.dropout(F.relu(model.l2(h1)))
y = model.l3(h2)
return np.argmax(y.data)
if __name__ == "__main__":
# 識別対象のCAPTCHA画像が格納されているファイルパスを定義
captcha_path = 'C:\MNIST\captcha\captcha0'
# 訓練用データ(MNIST)のファイルパスを定義
train_data_path = os.path.join('C:\\MNIST', 'mnist.pkl.gz')
# 正解ラベルの定義(結果表示用)
answerLabel = [0, 1, 4, 6, 7, 9]
# 予測対象データ(CAPTCHA画像)の取得
# 画像データを784次元のベクトルに変換
# RGB毎の配列からR要素のみを抽出(次元削減)
img_captcha = []
analize_data = []
captcha_files = os.listdir(captcha_path)
for file in captcha_files:
img_captcha = pylab.imread(os.path.join(captcha_path,file))
img_captcha_r = img_captcha[:, :, 0]
#img_captcha_r = img_captcha[:, :]
img_captcha_Array = np.asarray(img_captcha_r)
d_captcha = img_captcha_Array.shape[0] * img_captcha_Array.shape[1]
img_captcha_wide = img_captcha_Array.reshape(1, d_captcha)
analize_data.append(img_captcha_wide)
# 訓練データの取得
x_train, y_train, length = train_data_read(train_data_path)
x_train = x_train.astype(np.float32)
y_train = y_train.astype(np.int32)
# ニューラルネットワークの構築
# 入力層=784(28*28)、中間層=300、出力層=10(0~9)
model = FunctionSet(l1=F.Linear(784, 300),
l2=F.Linear(300, 300),
l3=F.Linear(300, 10))
# 確率的勾配降下法(SGD)で学習する際のバッチサイズ
# 10~100程度とすることが多いが、最も結果が良かった100とした。
batchsize = 100
# 学習の繰り返し回数
# 5回の学習で精度が95%を超えたため、5回とした。
learning_loop = 5
# SGDの設定
optimizer = optimizers.Adam()
optimizer.setup(model.collect_parameters())
# 学習
N = 50000
for epoch in range(1, learning_loop+1):
# 学習データの順番をランダムにする
perm = np.random.permutation(N)
# 0〜Nまでのデータをバッチサイズに区切って学習する
for i in range(0, N, batchsize):
x_batch = x_train[perm[i:i+batchsize]]
y_batch = y_train[perm[i:i+batchsize]]
# 重みの初期化
optimizer.zero_grads()
# フィードフォワードさせて誤差を算出
error = forward(x_batch, y_batch)
# バックプロパゲーションで勾配を算出
error.backward()
# 重みを更新
optimizer.update()
# CAPTCHAデータの予測
ok = 0
for i in range(len(analize_data)):
# 認識対象データを1個ずつ読み込む
x = analize_data[i].astype(np.float32)
# 認識対象の正解データを1個ずつ読み込む
y = answerLabel[i]
# CAPTCHAデータの予測
answer = predict(x)
# 予測値と正解データを標準出力する
print("No.{0:d} : predict => {1:d} , answer = > {2:d}".format(i, answer, int(y)))
# 予測値と正解データが一致している場合、ok(正解)を1インクリメントする
if int(y) == answer:
ok += 1
# ok(正解)の数と認識対象データ数を基に正解率を標準出力する
print("{0:05d} / {1:05d} = {2:3.2f}%".format(ok, len(analize_data), 100*ok/len(analize_data)))
피드 포워드나 백프로파게이션, 확률적 그라디언트 강하법(SGD)이나 드롭아웃 등의 테크닉이 매우 간이한 코드로 실현할 수 있다.
얼마나 멋진 도서관이야!
1. 해보자
조속히 이것을 사용해 CAPTCHA의 인식을 해 본다.
우선은 첫 번째 지금부터.
첫 번째 예측 결과No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 4 , answer = > 4
No.3 : predict => 6 , answer = > 6
No.4 : predict => 7 , answer = > 7
No.5 : predict => 9 , answer = > 9
00006 / 00006 = 100.00%
정답률은 100%.
이것은 지난번과 다르지 않다.
다음은 두 번째 이것이다.
두 번째 예측 결과No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 6 , answer = > 4
No.3 : predict => 8 , answer = > 6
No.4 : predict => 8 , answer = > 7
No.5 : predict => 9 , answer = > 9
00003 / 00006 = 50.00%
정답률은 50%.
전회는 33.33%였으므로, 개선되고 있는 것을 알 수 있다.
2. 정리
Chainer를 사용하여 숫자 이미지의 인식을 시도했습니다.
전회보다 정답률이 개선되고 있다.
학습 횟수를 늘리면 더욱 정답률은 올라갈 것으로 보이지만, 전회도 쓴 것처럼 학습 데이터를 궁리하지 않는 것은 근본 해결이 되지 않는다.
오히려 이번 검증에서 특필해야 할 것은, 매우 간이한 코드로 다층 퍼셉트론을 실장할 수 있어 게다가 정답률을 개선할 수 있었을 것이다.
앞으로 Chainer와 Deap을 사용하여 Neuroevolution을 구현하고 웹 응용 프로그램의 자동 크롤러를 개발하려고합니다.
3. 참고 문헌
No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 4 , answer = > 4
No.3 : predict => 6 , answer = > 6
No.4 : predict => 7 , answer = > 7
No.5 : predict => 9 , answer = > 9
00006 / 00006 = 100.00%
No.0 : predict => 0 , answer = > 0
No.1 : predict => 1 , answer = > 1
No.2 : predict => 6 , answer = > 4
No.3 : predict => 8 , answer = > 6
No.4 : predict => 8 , answer = > 7
No.5 : predict => 9 , answer = > 9
00003 / 00006 = 50.00%
Chainer를 사용하여 숫자 이미지의 인식을 시도했습니다.
전회보다 정답률이 개선되고 있다.
학습 횟수를 늘리면 더욱 정답률은 올라갈 것으로 보이지만, 전회도 쓴 것처럼 학습 데이터를 궁리하지 않는 것은 근본 해결이 되지 않는다.
오히려 이번 검증에서 특필해야 할 것은, 매우 간이한 코드로 다층 퍼셉트론을 실장할 수 있어 게다가 정답률을 개선할 수 있었을 것이다.
앞으로 Chainer와 Deap을 사용하여 Neuroevolution을 구현하고 웹 응용 프로그램의 자동 크롤러를 개발하려고합니다.
3. 참고 문헌
이상
Reference
이 문제에 관하여(기계 학습×웹 앱 진단: 다층 퍼셉트론으로 CAPTCHA를 인식한다(Chainer편)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/bbr_bbq/items/1864577f8280bca15ac1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)