弱监督的通用方案,CAM从图像级标签到像素级标签

简介

我们做深度学习中,到采用的训练方案是全监督的方式,这种全监督的方式,在基本的分类任务当中数据打标签的难度还好,但是在一些更多复杂的深度学习任务中,label的获取就有些困难了。
比如在图像分割领域当中,像素级的标签获取起来费事费力(labelme用起来还挺累的),有没有这么一种算法可以通过分类的标签衍生出像素级的标签,答案是有的。
CAM(Class Activation Mapping)就是目前所有弱监督算法的重要鼻祖。
在这里插入图片描述如图所示CAM前面的操作和FCN有些类似,先进行卷积以及下采样,后面进行反卷积复原图像,记住这个复原的channel要和分类网络的类是一样多的,之后经过GAP之后,在经过W相乘,得到分类,根据所选的分类回推权重,之后和反卷积得到的结果相乘累加,最后得到CAM。

代码实现

主干网络

import tensorflow as tf


x = tf.placeholder(tf.float32,[1, 224, 224, 3])#输入图片大小
y = tf.placeholder(tf.float32,[1, 10])#图像级别的标签

############主干网络
layer1=tf.layers.conv2d(x,40,3,strides=1, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=1, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)

反卷积,GAP和分类

layer1_transpose=tf.layers.conv2d_transpose(layer1,10,3,strides=8, padding='same')
layer1_transpose=tf.nn.relu(layer1_transpose)
print(layer1_transpose)
GAP=tf.keras.layers.GlobalAvgPool2D()(layer1_transpose)
print(GAP)

Weight=tf.Variable(tf.zeros([10, 10]))
print(Weight)
result=tf.matmul(GAP,Weight)
print(result)

CAM

##########CAM
idx=tf.argmax(result,1)
print(idx)
idx=idx[0]
Weight_choose=Weight[idx]
print(Weight_choose)
layer1_transpose=layer1_transpose*Weight_choose
print(layer1_transpose)
CAM=tf.reduce_sum(layer1_transpose,3)
print(CAM)

输出结果

Tensor("Relu_155:0", shape=(1, 224, 224, 40), dtype=float32)
Tensor("Relu_156:0", shape=(1, 112, 112, 40), dtype=float32)
Tensor("Relu_157:0", shape=(1, 56, 56, 40), dtype=float32)
Tensor("Relu_158:0", shape=(1, 56, 56, 40), dtype=float32)
Tensor("Relu_159:0", shape=(1, 28, 28, 40), dtype=float32)
Tensor("Relu_160:0", shape=(1, 224, 224, 10), dtype=float32)
Tensor("global_average_pooling2d_23/Mean:0", shape=(1, 10), dtype=float32)
<tf.Variable 'Variable_18:0' shape=(10, 10) dtype=float32_ref>
Tensor("MatMul_15:0", shape=(1, 10), dtype=float32)
Tensor("ArgMax_14:0", shape=(1,), dtype=int64)
Tensor("strided_slice_18:0", shape=(10,), dtype=float32)
Tensor("mul_5:0", shape=(1, 224, 224, 10), dtype=float32)
Tensor("Sum:0", shape=(1, 224, 224), dtype=float32)

完整代码

# -*- coding: utf-8 -*-
"""
Created on Sat Jul 18 10:55:42 2020

@author: surface
"""

#################弱监督CAM
import tensorflow as tf


x = tf.placeholder(tf.float32,[1, 224, 224, 3])#输入图片大小
y = tf.placeholder(tf.float32,[1, 10])#图像级别的标签

############主干网络
layer1=tf.layers.conv2d(x,40,3,strides=1, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=1, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)
layer1=tf.layers.conv2d(layer1,40,3,strides=2, padding='same')
layer1=tf.nn.relu(layer1)
print(layer1)


###########分类
layer1_transpose=tf.layers.conv2d_transpose(layer1,10,3,strides=8, padding='same')
layer1_transpose=tf.nn.relu(layer1_transpose)
print(layer1_transpose)
GAP=tf.keras.layers.GlobalAvgPool2D()(layer1_transpose)
print(GAP)

Weight=tf.Variable(tf.zeros([10, 10]))
print(Weight)
result=tf.matmul(GAP,Weight)
print(result)

##########CAM
idx=tf.argmax(result,1)
print(idx)
idx=idx[0]
Weight_choose=Weight[idx]
print(Weight_choose)
layer1_transpose=layer1_transpose*Weight_choose
print(layer1_transpose)
CAM=tf.reduce_sum(layer1_transpose,3)
print(CAM)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值