自动驾驶与CAPTCHA破解:从训练到实战
自动驾驶训练与成果
在自动驾驶的训练过程中,我们使用了一系列的函数和参数设置。首先,定义了一些关键的参数和函数:
from keras import backend as K
import numpy as np
import shutil, os
import pandas as pd
from scipy import misc
import pickle
import matplotlib.pyplot as plt
from sklearn.externals import joblib
huber_loss_thresh = 1
action_list = np.array([
[0.0, 0.0, 0.0], # Brake
[-0.6, 0.05, 0.0], # Sharp left
[0.6, 0.05, 0.0], # Sharp right
[0.0, 0.3, 0.0] # Straight
])
rgb_mode = True
num_actions = len(action_list)
def sel_action(action_index):
return action_list[action_index]
def sel_action_index(action):
for i in range(num_actions):
if np.all(action == action_list[i]):
return i
raise ValueError('Selected action not in list')
def huber_loss(y_true, y_pred):
error = (y_true - y_pred)
cond = K.abs(error) <= huber_loss_thresh
if cond == True:
loss = 0.5 * K.square(error)
else:
loss = 0.5 * huber_loss_thresh**2 + huber_loss_thresh*(K.abs(error) - huber_loss_thresh)
return K.mean(loss)
def rgb2gray(rgb, norm=True):
gray = np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
if norm:
gray = gray.astype('float32') / 128 - 1
return gray
def data_store(path, action, reward, state):
if not os.path.exists(path):
os.makedirs(path)
else:
shutil.rmtree(path)
os.makedirs(path)
df = pd.DataFrame(action, columns=["Steering", "Throttle", "Brake"])
df["Reward"] = reward
df.to_csv(path + 'car_racing_actions_rewards.csv', index=False)
for i in range(len(state)):
if rgb_mode == False:
image = rgb2gray(state[i])
else:
image = state[i]
misc.imsave(path + "img" + str(i) + ".png", image)
def model_save(path, name, agent, R):
if not os.path.exists(path):
os.makedirs(path)
agent.DQN.model.save(path + name)
print(name, "saved")
print('...')
joblib.dump(agent.memory, path + name + 'Memory')
joblib.dump([agent.epsilon, agent.steps, agent.DQN.opt.get_config()], path + name + 'AgentParam')
joblib.dump(R, path + name + 'Rewards')
print('Memory pickle dumped')
训练自动驾驶模型可以使用以下命令:
python main.py --environment_name 'CarRacing-v0' --model_path '/home/santanu/Autonomous Car/train/' --train_mode True --test_mode False --epsilon_greedy True --render True --width 96 --height 96 --num_stack 4 --huber_loss_thresh 1 --dropout 0.2 --memory_size 10000 --batch_size 128 --max_num_episodes 500
训练初期,自动驾驶汽车会犯错,但随着训练的进行,它会从错误中学习并不断改进。以下是训练过程的简单流程图:
graph LR
A[开始训练] --> B[执行动作]
B --> C[获取奖励和新状态]
C --> D[存储数据]
D --> E[更新模型]
E --> F{是否达到最大训练轮数}
F -- 否 --> B
F -- 是 --> G[训练结束]
训练成果通过截图展示,初期汽车会犯错,而经过足够的训练后,汽车能够成功驾驶。
CAPTCHA相关知识与操作
CAPTCHA简介
CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)是一种用于区分人类用户和机器或机器人的计算机程序,通常作为防止垃圾邮件和数据滥用的安全措施。其概念最早于1997年由AltaVista的首席科学家Andrei Broder提出,2003年由Luis von Ahn等人完善。常见的CAPTCHA形式是要求用户识别扭曲图像中的字母和数字,人类能够轻松识别,而自动化程序或机器人则难以做到。近年来,CAPTCHA的作用不仅限于防止机器人欺诈,例如谷歌在数字化《纽约时报》档案和谷歌图书时使用了CAPTCHA及其变体reCAPTCHA。
技术要求
- 具备Python 3、TensorFlow、Keras和OpenCV的基础知识。
- 代码文件可在GitHub上找到:https://github.com/PacktPublishing/Intelligent-Projects-using-Python/tree/master/Chapter10
- 查看代码运行视频:http://bit.ly/2SgwR6P
生成基本CAPTCHA
可以使用Python的Claptcha包生成由数字和字母组成的四位CAPTCHA图像。以下是生成代码:
import numpy as np
from claptcha import Claptcha
import matplotlib.pyplot as plt
alphabets = 'abcdefghijklmnopqrstuvwxyz'
alphabets = alphabets.upper()
font = "/home/santanu/Android/Sdk/platforms/android-28/data/fonts/DancingScript-Regular.ttf"
char_num_ind = list(np.random.randint(0, 2, 4))
text = ''
for ind in char_num_ind:
if ind == 1:
loc = np.random.randint(0, 26, 1)
text = text + alphabets[np.random.randint(0, 26, 1)[0]]
else:
text = text + str(np.random.randint(0, 10, 1)[0])
c = Claptcha(text, font)
text, image = c.image
plt.imshow(image)
生成的CAPTCHA图像会添加一些噪声,如水平方向的扭曲线条。
生成训练数据
为了训练用于破解CAPTCHA的CNN模型,需要生成训练集、验证集和测试集。以下是生成数据的脚本
CaptchaGenerator.py
:
from claptcha import Claptcha
import os
import numpy as np
import cv2
import fire
from elapsedtimer import ElasedTimer
def generate_captcha(outdir, font, num_captchas=20000):
alphabets = 'abcdefghijklmnopqrstuvwxyz'
alphabets = alphabets.upper()
try:
os.mkdir(outdir)
except:
'Directory already present, writing captchas to the same'
for i in range(num_captchas):
char_num_ind = list(np.random.randint(0, 2, 4))
text = ''
for ind in char_num_ind:
if ind == 1:
loc = np.random.randint(0, 26, 1)
text = text + alphabets[np.random.randint(0, 26, 1)[0]]
else:
text = text + str(np.random.randint(0, 10, 1)[0])
c = Claptcha(text, font)
text, image = c.image
image.save(outdir + text + '.png')
def main_process(outdir_train, num_captchas_train,
outdir_val, num_captchas_val,
outdir_test, num_captchas_test,
font):
generate_captcha(outdir_train, font, num_captchas_train)
generate_captcha(outdir_val, font, num_captchas_val)
generate_captcha(outdir_test, font, num_captchas_test)
if __name__ == '__main__':
with ElasedTimer('main_process'):
fire.Fire(main_process)
可以使用以下命令生成大小为16000、4000和4000的训练集、验证集和测试集:
python CaptchaGenerator.py --outdir_train '/home/santanu/Downloads/Captcha Generation/captcha_train/' --outdir_test '/home/santanu/Downloads/Captcha Generation/captcha_test/' --num_captchas_test 4000 --fo
脚本生成这些数据大约需要3.328分钟。
CAPTCHA破解CNN架构
使用CNN架构识别CAPTCHA中的字符,该架构在密集层之前有两对卷积和池化层。将CAPTCHA拆分为四个字符,分别输入模型,最终输出层预测36个类别之一(26个字母和10个数字)。以下是模型定义代码:
from keras.layers import Input, Conv2D, MaxPooling2D, Dropout, Flatten, Dense
from keras.models import Model
def _model_(n_classes):
input_ = Input(shape=(40, 25, 1))
x = Conv2D(20, (5, 5), padding="same", activation="relu")(input_)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(x)
x = Dropout(0.2)(x)
x = Conv2D(50, (5, 5), padding="same", activation="relu")(x)
x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2))(x)
x = Dropout(0.2)(x)
x = Flatten()(x)
x = Dense(1024, activation="relu")(x)
out = Dense(n_classes, activation='softmax')(x)
model = Model(inputs=[input_], outputs=out)
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
return model
该模型的架构可以用以下表格简单概括:
| 层类型 | 描述 |
| ---- | ---- |
| 输入层 | 形状为(40, 25, 1) |
| 卷积层1 | 20个滤波器,(5, 5)卷积核,ReLU激活函数 |
| 池化层1 | 池化大小(2, 2),步长(2, 2) |
| 丢弃层1 | 丢弃率0.2 |
| 卷积层2 | 50个滤波器,(5, 5)卷积核,ReLU激活函数 |
| 池化层2 | 池化大小(2, 2),步长(2, 2) |
| 丢弃层2 | 丢弃率0.2 |
| 全连接层1 | 1024个节点,ReLU激活函数 |
| 输出层 | 36个节点,Softmax激活函数 |
自动驾驶与CAPTCHA破解:从训练到实战
训练CAPTCHA破解模型
在生成了训练所需的CAPTCHA数据后,接下来就是训练CAPTCHA破解模型。为了实现这一目标,还需要定义一些辅助函数和类。
import cv2
import keras
import numpy as np
import pandas as pd
def load_img(path, dim=(100, 40)):
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, dim)
img = img.reshape((dim[1], dim[0], 1))
return img / 255.
def create_dict_char_to_index():
chars = 'abcdefghijklmnopqrstuvwxyz0123456789'.upper()
chars = list(chars)
index = np.arange(len(chars))
char_to_index_dict, index_to_char_dict = {}, {}
for v, k in zip(index, chars):
char_to_index_dict[k] = v
index_to_char_dict[v] = k
return char_to_index_dict, index_to_char_dict
class DataGenerator(keras.utils.Sequence):
def __init__(self, dest, char_to_index_dict, batch_size=32, n_classes=36, dim=(40, 100, 1), shuffle=True):
self.dest = dest
self.files = os.listdir(self.dest)
self.char_to_index_dict = char_to_index_dict
self.batch_size = batch_size
self.n_classes = n_classes
self.dim = (40, 100)
self.shuffle = shuffle
self.on_epoch_end()
def __len__(self):
return int(np.floor(len(self.files) / self.batch_size))
def __getitem__(self, index):
indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]
list_files = [self.files[k] for k in indexes]
X, y = self.__data_generation(list_files)
return X, y
def on_epoch_end(self):
self.indexes = np.arange(len(self.files))
if self.shuffle == True:
np.random.shuffle(self.indexes)
def __data_generation(self, list_files):
dim_h = self.dim[0]
dim_w = self.dim[1] // 4
channels = 1
X = np.empty((4 * len(list_files), dim_h, dim_w, channels))
y = np.empty((4 * len(list_files)), dtype=int)
k = -1
for f in list_files:
target = list(f.split('.')[0])
target = [self.char_to_index_dict[c] for c in target]
img = load_img(self.dest + f)
img_h, img_w = img.shape[0], img.shape[1]
crop_w = img.shape[1] // 4
for i in range(4):
img_crop = img[:, i * crop_w:(i + 1) * crop_w]
k += 1
X[k, ] = img_crop
y[k] = int(target[i])
return X, y
训练CAPTCHA破解模型的函数如下:
def train(dest_train, dest_val, outdir, batch_size, n_classes, dim, shuffle, epochs, lr):
char_to_index_dict, index_to_char_dict = create_dict_char_to_index()
model = _model_(n_classes)
train_generator = DataGenerator(dest_train, char_to_index_dict, batch_size, n_classes, dim, shuffle)
val_generator = DataGenerator(dest_val, char_to_index_dict, batch_size, n_classes, dim, shuffle)
model.fit_generator(train_generator, epochs=epochs, validation_data=val_generator)
model.save(outdir + 'captcha_breaker.h5')
可以使用以下命令运行
captcha_solver.py
脚本进行训练:
python captcha_solver.py train --dest_train '/home/santanu/Downloads/Captcha Generation/captcha_train/'
训练过程的流程图如下:
graph LR
A[开始训练] --> B[创建数据生成器]
B --> C[加载模型]
C --> D[训练模型]
D --> E[保存模型]
E --> F[训练结束]
在仅20个训练周期内,模型在CAPTCHA字符级别的验证准确率约达到98.3%。以下是训练过程的部分输出日志:
Epoch 17/20
1954/1954 [==============================] - 14s 7ms/step - loss: 0.0340 - acc: 0.9896 - val_loss: 0.0
Epoch 18/20
1954/1954 [==============================] - 13s 7ms/step - loss: 0.0310 - acc: 0.9904 - val_loss: 0.0
Epoch 19/20
1954/1954 [==============================] - 13s 7ms/step - loss: 0.0315 - acc: 0.9904 - val_loss: 0.0
Epoch 20/20
1954/1954 [==============================] - 13s 7ms/step - loss: 0.0297 - acc: 0.9910 - val_loss: 0.0
4.412 min: captcha_solver
使用GeForce GTX 1070 GPU进行20个周期的训练,大约需要4.412分钟,建议使用基于GPU的机器以加快训练速度。
测试CAPTCHA破解模型
训练好模型后,需要在测试数据集上评估模型的性能。以下是用于运行测试集推理的
evaluate
函数:
def evaluate(model_path, eval_dest, outdir, fetch_target=True):
char_to_index_dict, index_to_char_dict = create_dict_char_to_index()
files = os.listdir(eval_dest)
model = keras.models.load_model(model_path)
predictions, targets = [], []
for f in files:
if fetch_target == True:
target = list(f.split('.')[0])
targets.append(target)
pred = []
img = load_img(eval_dest + f)
img_h, img_w = img.shape[0], img.shape[1]
crop_w = img.shape[1] // 4
for i in range(4):
img_crop = img[:, i * crop_w:(i + 1) * crop_w]
img_crop = img_crop[np.newaxis, :]
pred_index = np.argmax(model.predict(img_crop), axis=1)
pred_char = index_to_char_dict[pred_index[0]]
pred.append(pred_char)
predictions.append(pred)
df = pd.DataFrame()
df['files'] = files
df['predictions'] = predictions
if fetch_target == True:
match = []
df['targets'] = targets
accuracy_count = 0
for i in range(len(files)):
if targets[i] == predictions[i]:
accuracy_count += 1
match.append(1)
else:
match.append(0)
print(f'Accuracy: {accuracy_count / float(len(files))} ')
eval_file = outdir + 'evaluation.csv'
df['match'] = match
df.to_csv(eval_file, index=False)
print(f'Evaluation file written at: {eval_file} ')
可以使用以下命令运行
captcha_solver.py
脚本的
evaluate
函数进行推理:
python captcha_solver.py evaluate --model_path /home/santanu/ML_DS_Catalog-/captcha/model/captcha_breaker.h5 --eval_dest '/home/santanu/Downloads/Captcha Generation/captcha_test/' --outdir /home/santanu/ML_DS_Catalog-/captcha/ --fetch_target True
在4000个CAPTCHA的测试数据集上,模型的准确率约为93%。以下是运行
evaluate
函数的输出:
Accuracy: 0.9320972187421699
Evaluation file written at: /home/santanu/ML_DS_Catalog-/captcha/evaluation.csv
13.564 s: captcha_solver
推理4000个CAPTCHA大约需要14秒,评估结果会写入
/home/santanu/ML_DS_Catalog-/captcha/evaluation.csv
文件。同时,还可以查看模型在哪些CAPTCHA上表现不佳,这有助于进一步分析和改进模型。
综上所述,通过一系列的步骤,我们实现了自动驾驶模型的训练和CAPTCHA破解模型的训练与测试。自动驾驶模型从最初的犯错到逐渐学会正确驾驶,而CAPTCHA破解模型在测试集上也取得了较高的准确率。这些成果展示了深度学习在实际应用中的强大能力,但同时也提醒我们需要不断改进CAPTCHA技术以应对日益强大的破解手段。
超级会员免费看

被折叠的 条评论
为什么被折叠?



