前言
在之前的博客中,我们简单的完成了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
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优势的,完整代码我会上传。