在之前的博客中,我们简单的完成了CAM算法的伪代码,地址: https://blog.csdn.net/qq_43534932/article/details/107425740 没有进行真正的实操,我们采用了cifar10这个小数据集,来完成CAM基本功能的实现。 cifar10数据集:是由CIFAR(Candian Institute For Advanced Research) 收集整理的一个用于机器学习和图像识别问题的数据集。这个数据集共有60000张32 * 32的涵盖10个分类的彩色图片。具体分类如下图所示:
在之前的博客中我们也介绍了CAM,CAM采用的是迁移学习的方案,首先要训练一个分类模型
image_holder = tf.placeholder(tf.float32, [None, 24, 24, 3]) label_holder = tf.placeholder(tf.int32, [None]) layer1=tf.layers.conv2d(image_holder,64,5,strides=1, padding='same') layer1=tf.nn.relu(layer1) layer1=model.Resblock(layer1,3,1,32) #layer1=model.SK_block(layer1,3,5,128) layer1=model.Resblock(layer1,5,1,32) #layer1=tf.nn.max_pool(layer1, 5, 2, padding="SAME") layer1=model.Resblock(layer1,3,1,32) #layer1=tf.nn.max_pool(layer1, 5, 2, padding="SAME") layer1=model.Resblock(layer1,3,1,32) #layer1=tf.nn.max_pool(layer1, 5, 2, padding="SAME") layer1=model.Resblock(layer1,3,1,32) layer1=model.Resblock(layer1,3,1,32) ###########分类 layer1_transpose=tf.layers.conv2d_transpose(layer1,10,3,strides=1, padding='same') layer1_transpose=tf.nn.relu(layer1_transpose) print(layer1_transpose) GAP=tf.keras.layers.GlobalAvgPool2D()(layer1_transpose) print(GAP) # 全连接层,隐含层节点数下降了一半 '''正态分布标准差设为上一个隐含层节点数的倒数,且不计入L2的正则''' weight5 = variable_with_weight_loss(shape=[10, 10], stddev=1 / 10, w1=0.0) bias5 = tf.Variable(tf.constant(0.0, shape=[10])) logits = tf.add(tf.matmul(GAP, weight5), bias5)基于cifair数据集,我们没有像文章里那样降采样,因为我们发现,降采样后复原的结果是有很大问题的。 这里面我们写了个model模块,里面有Resblock,和SKblock等等。 基于此,因为算力和时间的关系,我们粗浅的训练了一个准确率在80%左右的模型。
CAM算法和之前复现的伪代码类似,但是还要加入模型读取功能,把相应layer层读取出来,进行计算,完成CAM
data_dir = './cifar10_data/cifar-10-batches-bin' images_test, labels_test = cifar10_input.inputs(eval_data=True, data_dir=data_dir, batch_size=1) print(images_test,labels_test) saver = tf.train.import_meta_graph( './Mobel_service/best.ckpt.meta')# 加载图结构 gragh = tf.get_default_graph()# 获取当前图,为了后续训练时恢复变量 tensor_name_list = [tensor.name for tensor in gragh.as_graph_def().node]# 得到当前图中所有变量的名称 #print(tensor_name_list) x = gragh.get_tensor_by_name('Placeholder:0') y = gragh.get_tensor_by_name('Placeholder_1:0') feature = gragh.get_tensor_by_name('Relu_20:0') weights = gragh.get_tensor_by_name('global_average_pooling2d_1/Mean:0') CAM = tf.reduce_sum(feature*weights, -1) print(CAM) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.train.start_queue_runners() image_batch, label_batch = sess.run([images_test, labels_test]) CAM_result=sess.run([CAM], feed_dict={x: image_batch, y: label_batch}) CAM_result = np.reshape(CAM_result, [24,24]) print(CAM_result.shape) ###显示 image_batch = np.reshape(image_batch, [24,24,3]) plt.figure() plt.subplot(1,2,1) plt.imshow(image_batch, interpolation = 'bilinear') plt.subplot(1,2,2) plt.imshow(CAM_result, interpolation = 'bilinear') plt.show() ##### print(image_batch.shape) print(label_batch.shape)抛去我们图片读取的分率有点糊,我们可以看出,其实还是能显示出一定的CAM优势的,完整代码我会上传。