之前借助简单搭建的cnn模型执行验证码的分类任务训练,https://blog.csdn.net/weixin_41044499/article/details/94382397,由于缺乏训练多层神经网络的设备和条件,准确率并不高。这里通过借助vgg19的模型来抽取验证码图片的特征,再增加一个全连接层,做简单的分类问题。
相比多种调取现有cnn模型的方案,使用keras的vgg16直接操作的方式,安装和使用最为方便。
方法参考了这篇文章 https://blog.csdn.net/data_scientist/article/details/79041240
# -*- coding:utf-8 -*- # /usr/bin/python from keras.applications.vgg19 import VGG19 from keras.preprocessing import image from keras.applications.vgg19 import preprocess_input from keras.models import Model import numpy as np base_model = VGG19(weights='imagenet') for layer in base_model.layers: print(layer.name) model = Model(inputs=base_model.input, outputs=base_model.get_layer('predictions').output) data = np.empty((300,1000),dtype="float32") y=[] ##打开图片 for index,i in enumerate('ABC'): print(index) for j in range(0,100): img = image.load_img("yanzhengma2/"+i+'-'+str(j)+'.jpg', target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) block4_pool_features = model.predict(x) ##把图片转换成数组形式 data[index*100+j] = np.asarray(block4_pool_features,dtype="float32") y.append(index) from sklearn import preprocessing enc = preprocessing.OneHotEncoder() enc.fit(np.array(y).reshape(-1, 1)) # fit来学习编码 y_new = enc.transform(np.array(y).reshape(-1, 1)).toarray() np.savetxt("a.txt", data) # 缺省按照'%.18e'格式保存数据,以空格分隔 np.savetxt("b.txt", y_new,fmt="%d")
将图片像素经过vgg的转化后参数,保存到txt中。
# -*- coding:utf-8 -*- # /usr/bin/python import numpy as np x = np.loadtxt("a.txt") y = np.loadtxt("b.txt") # np.savetxt("a.txt", data) # 缺省按照'%.18e'格式保存数据,以空格分隔 # np.savetxt("b.txt", y_new) import tensorflow as tf import numpy as np ## 原始数据 with tf.name_scope('data'): x = np.loadtxt("a.txt") y = np.loadtxt("b.txt") ## 创建参数,嵌套关系 with tf.name_scope('parameters'): ##权重 with tf.name_scope('weights'): weight = tf.Variable(tf.random_uniform([1000,3],-1.0,1.0)) tf.summary.histogram('weight',weight) ##偏置 with tf.name_scope('biases'): bias = tf.Variable(tf.zeros([1,3])) tf.summary.histogram('bias',bias) ##get y_prediction with tf.name_scope('y_prediction'): predict_y = tf.nn.softmax(tf.matmul(tf.cast(x,tf.float32), weight) + bias) ##compute the loss with tf.name_scope('loss'): loss =tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predict_y, labels=y)) tf.summary.scalar('loss',loss) ##creat optimizer optimizer = tf.train.AdamOptimizer(learning_rate=1e-3) #creat train ,minimize the loss with tf.name_scope('train'): train = optimizer.minimize(loss) #creat init with tf.name_scope('init'): init = tf.global_variables_initializer() ##creat a Session sess = tf.Session() #merged merged = tf.summary.merge_all() ##initialize writer = tf.summary.FileWriter("logs/", sess.graph) sess.run(init) ## Loop for step in range(1000): sess.run(train) rs=sess.run(merged) writer.add_summary(rs, step) if step % 25 == 0: correct_prediction = tf.equal(tf.argmax(predict_y, 1), tf.argmax(y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) accuracy_value = sess.run(accuracy) print('step:%d accuracy:%.4f' % (step, accuracy_value))
对获得转化后的1000个变量,只加了一层全连接,经过多轮迭代后,准确率达到了100%,说明迁移学习的作用很大,用现有模型做特征抽取很有效果。