卷积的目的是为了从图像中提取特征。
可以从输入的一小块数据中学到图像的特征,并且可以保留像素间的空间关系。
下面用一张图来表示卷积的具体 *** 作:
池化可以降低输入表示的空间尺度,是输入特征维度变小,也会使网络中的参数和计算的数量更加可控的变小,因此可以控制过拟合。
空间池化有最大化、平均化、加和等方式。
卷积神经网络相当于全连接神经网络的改进,最大的不同是:卷积神经网络相邻层之间的神经单元不是全连接的,而是部分连接的。
也就是说,某个神经元的感知域来自于上层的部分神经单元,而不是与所有的神经元相连接。
import tensorflow as tf
import numpy as np
import random
from captcha.image import ImageCaptcha
from matplotlib import pyplot as plt
# 验证码识别
numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
def gen_random_captcha_text(char_set=None):
if char_set is None:
char_set = numbers
captcha_text = []
for i in range(4):
captcha_text.append(random.choice(char_set))
return captcha_text
def gen_captcha():
image_captcha = ImageCaptcha()
captcha_text = gen_random_captcha_text()
# 生成Image对象
captcha_image = image_captcha.generate_image(captcha_text)
# 转换成array对象
captcha_image = np.array(captcha_image)
return captcha_text, captcha_image
def text2vec(text):
vector = np.zeros(40)
for i in range(len(text)):
index = i * 10 + ord(text[i]) - 48
vector[index] = 1
return vector
def vec2text(vec):
text = []
for i, c in enumerate(vec):
text.append(numbers[c])
return "".join(text)
def get_batch(size=100):
batch_x = np.zeros([size, 9600])
batch_y = np.zeros([size, 40])
for i in range(size):
text, image = gen_captcha()
batch_x[i, :] = np.mean(image, -1).flatten() / 255
batch_y[i, :] = text2vec(text)
return batch_x, batch_y
train_images, train_labels = get_batch(1000)
train_images = train_images.reshape((-1, 60, 160, 1))
train_labels = train_labels.reshape((-1, 4, 10))
test_images, test_labels = get_batch(10)
test_images = test_images.reshape((-1, 60, 160, 1))
test_labels = test_labels.reshape((-1, 4, 10))
# 创建模型
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation="relu"),
tf.keras.layers.MaxPooling2D((2, 2), 2),
tf.keras.layers.Conv2D(64, (3, 3), activation="relu"),
tf.keras.layers.MaxPooling2D((2, 2), 2),
tf.keras.layers.Dropout(0.25),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(1000, activation="relu"),
tf.keras.layers.Dense(40),
tf.keras.layers.Reshape([4, 10]),
tf.keras.layers.Softmax()
])
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
# from_logits=True 标志位将softmax激活函数实现在损失函数中,便不需要手动添加softmax损失函数
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),
metrics=['accuracy'])
# 训练模型
history = model.fit(train_images, train_labels, epochs=10)
# 模型评估
accuracy = history.history["accuracy"]
loss = history.history["loss"]
epochs = range(10)
plt.figure(1)
plt.subplot(1, 2, 1)
plt.plot(epochs, accuracy, label="train accuracy")
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(epochs, loss, label="train loss")
plt.legend()
# 预测模型
plt.figure(2, figsize=(10, 10))
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(train_images[i].reshape(-1, 160))
plt.xticks([])
plt.yticks([])
predict_label = model.predict(train_images[i].reshape((-1, 60, 160, 1)))
print(np.argmax(predict_label, axis=2))
plt.xlabel(vec2text(np.argmax(predict_label, axis=2)[0]))
plt.show()
测试结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)