from captcha.image import ImageCaptcha
import os
import string
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import cv2
import random
chars = string.digits # 验证码字符集
nclass=len(chars)+1
print(nclass)
#生成验证码
def generate_img(img_dir: '图片保存目录'='img_dir'):
for length in range(4, 8): # 验证码长度
if not os.path.exists(f'{img_dir}/{length}'):
os.makedirs(f'{img_dir}/{length}')
for _ in range(1000):
img_generator = ImageCaptcha()
char = ''.join([random.choice(chars) for _ in range(length)])
img_generator.write(chars=char, output=f'{img_dir}/{length}/{char}_{_}.jpg')
# generate_img("./image")
char_map = {chars[c]: c for c in range(len(chars))} # 验证码编码(0到len(chars) - 1)
#处理图片
def load_img(img_dir: '图片保存目录'='img_dir', min_length: '最小长度'=4, max_length: '最大长度'=7):
labels = {length: [] for length in range(min_length, max_length + 1)} # 验证码真实标签{长度:标签列表}
imgs = {length: [] for length in range(min_length, max_length + 1)} # 图片BGR数据字典{长度:BGR数据列表}
### 读取图片
for length in range(min_length, max_length + 1):
for file in os.listdir(f'{img_dir}/{length}'):
img = cv2.imread(f'{img_dir}/{length}/{file}')
labels[length].append(file[:-4].split('_')[0])
height, width, _ = img.shape
h_resize = 32
w_resize = int(img.shape[1] * h_resize / img.shape[0])
img_gray = cv2.cvtColor(cv2.resize(img, (w_resize, h_resize)), cv2.COLOR_BGR2GRAY) # 缩小图片固定宽度为32,并转为灰度图
imgs[length].append(img_gray)
### 编码真实标签
labels_encode = {length: [] for length in range(min_length, max_length + 1)}
for length in range(min_length, max_length + 1):
for label in labels[length]:
label = [char_map[i] for i in label]
labels_encode[length].append(label)
return imgs, labels,labels_encode
def generate_data(imgs, labels_encode,length ):
imgs = {length: np.array(imgs[length]) for length in range(4, 8)} # 图片BGR数据字典{长度:BGR数据数组}
labels_encode = {length: np.array(labels_encode[length]) for length in range(4, 8)} # 验证码真实标签{长度:标签数组}
x=imgs[length]
x=x.reshape(-1,32,85,1)
y=labels_encode[length]
return [x, y,np.ones(len(x)) * int(42),np.ones(len(x)) * int(len(y[0]))],np.ones(len(x))
def ctc_lambda_func(args):
y_pred, labels, input_length, label_length = args
# y_pred = y_pred[:, 2:, :]
return keras.backend.ctc_batch_cost(labels, y_pred, input_length, label_length)
input_tensor=keras.layers.Input(shape=(32,None,1))
x=keras.layers.Conv2D(32,kernel_size=3, padding='same', kernel_initializer='he_uniform',activation='relu')(input_tensor)
x=keras.layers.BatchNormalization()(x)
x=keras.layers.MaxPool2D((2,2))(x)
x=keras.layers.Conv2D(64,kernel_size=3, padding='same', kernel_initializer='he_uniform',activation='relu')(x)
x=keras.layers.BatchNormalization()(x)
x=keras.layers.Conv2D(64,kernel_size=3, padding='same', kernel_initializer='he_uniform',activation='relu')(x)
x = keras.layers.Permute((2, 1, 3))(x)
x =keras.layers.TimeDistributed(keras.layers.Flatten())(x)
x = keras.layers.Bidirectional(keras.layers.GRU(128, return_sequences=True,reset_after=False))(x)
x = keras.layers.Bidirectional(keras.layers.GRU(128, return_sequences=True,reset_after=False))(x)
x = keras.layers.Dense(nclass, activation='softmax')(x)
base_model = keras.Model(inputs=input_tensor, outputs=x)
labels=keras.layers.Input(shape=[None,],dtype=tf.float32,name='labels')
input_length=keras.layers.Input(shape=[1],dtype=tf.int64,name='input_length')
labels_length=keras.layers.Input(shape=[1],dtype=tf.int64,name='labels_length')
loss_out=keras.layers.Lambda(ctc_lambda_func,output_shape=(1,),name='ctc')([x,labels,input_length,labels_length])
model=keras.Model(inputs=[input_tensor,labels,input_length,labels_length],outputs=loss_out)
# 模型优化器
sgd = keras.optimizers.SGD(lr=0.0001, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5)
model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=sgd)
model.summary()
imgs, labels,labels_encode=load_img("./image/",4,7)
# for i in range(4,8):
model.fit_generator(generate_data(imgs, labels_encode, 4),epochs=10)
出现这样的错误:ValueError: No gradients provided for any variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'batch_normalization/gamma:0', 'batch_normalization/beta:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'batch_normalization_1/gamma:0', 'batch_normalization_1/beta:0', 'conv2d_2/kernel:0', 'conv2d_2/bias:0', 'bidirectional/forward_gru/gru_cell_1/kernel:0', 'bidirectional/forward_gru/gru_cell_1/recurrent_kernel:0', 'bidirectional/forward_gru/gru_cell_1/bias:0', 'bidirectional/backward_gru/gru_cell_2/kernel:0', 'bidirectional/backward_gru/gru_cell_2/recurrent_kernel:0', 'bidirectional/backward_gru/gru_cell_2/bias:0', 'bidirectional_1/forward_gru_1/gru_cell_4/kernel:0', 'bidirectional_1/forward_gru_1/gru_cell_4/recurrent_kernel:0', 'bidirectional_1/forward_gru_1/gru_cell_4/bias:0', 'bidirectional_1/backward_gru_1/gru_cell_5/kernel:0', 'bidirectional_1/backward_gru_1/gru_cell_5/recurrent_kernel:0', 'bidirectional_1/backward_gru_1/gru_cell_5/bias:0', 'dense/kernel:0', 'dense/bias:0'].
求大神帮忙解决!!!!