第十五节,利用反卷积技术复原卷积网络各层图像
在第十三节,我们已经介绍了使用带有全局平均池化层的CNN对CIFAR10数据集分类,在学习了反卷积神经网络之后我们把第十三节那个程序里的卷积层可视化出来。
一 替换掉tf.nn.max_pool()函数
这里不再使用自己定义的max_pool_2x2函数,改成新加入的带有mask返回值得max_pool_with_argmax()函数:
#定义占位符 使用反卷积函数,占位符中必须指定具体数,不能指定None input_x = tf.placeholder(dtype=tf.float32,shape=[batch_size,24,24,3]) #图像大小24x24x input_y = tf.placeholder(dtype=tf.float32,shape=[batch_size,10]) #0-9类别 x_image = tf.reshape(input_x,[batch_size,24,24,3]) #不能传入-1 否则会报错 #1.卷积层 ->池化层 W_conv1 = weight_variable([5,5,3,64]) b_conv1 = bias_variable([64]) h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1) + b_conv1) #输出为[-1,24,24,64] print_op_shape(h_conv1) h_pool1,mask1 = max_pool_with_argmax(h_conv1,2) #输出为[-1,12,12,64] print_op_shape(h_pool1) #2.卷积层 ->池化层 W_conv2 = weight_variable([5,5,64,64]) b_conv2 = bias_variable([64]) h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2) #输出为[-1,12,12,64] print_op_shape(h_conv2) h_pool2,mask2 = max_pool_with_argmax(h_conv2,2) #输出为[-1,6,6,64] print_op_shape(h_pool2)
二 反卷积第二层卷积结果
以第二池化输出的变量h_pool2为开始部分,沿着h_pool2生成的方式反向操作一层一层推导,直至生成原始图t1_x_image。
如图所示,上半部分是h_pool2卷积过程,下半部分为反卷积过程,为了分析方便,下半部分名称与代码中的变量一致。
#3 反卷积第二层卷积结果 t_conv2 = un_max_pool(h_pool2,mask2,2) print_op_shape(t_conv2) #输出为[128,12,12,64] t_pool1 = tf.nn.conv2d_transpose(t_conv2 - b_conv2,W_conv2,output_shape=h_pool1.shape,strides=[1,1,1,1],padding='SAME') print_op_shape(t_pool1) #输出为[128,12,12,64] t_conv1 = un_max_pool(t_pool1,mask1,2) print_op_shape(t_conv1) #输出为[128,24,24,64] t_x_image = tf.nn.conv2d_transpose(t_conv1 - b_conv1,W_conv1,output_shape=x_image.shape,strides=[1,1,1,1],padding='SAME') #生成原始图 print_op_shape(t_x_image) #输出为[128,24,25,3]
因为在卷积过程中,每个卷积后都要加上权重b,所以在反卷积过程中就要将b减去,由于Relu函数基本上恒等变化(除了小于0的部分),所以在反向时不需要可逆操作,可以直接忽略去。
三 反卷积第一层卷积结果
#4 反卷积第一层卷积结果 t1_conv1 = un_max_pool(h_pool1,mask1,2) print_op_shape(t1_conv1) t1_x_image = tf.nn.conv2d_transpose(t1_conv1 - b_conv1,W_conv1,output_shape=x_image.shape,strides=[1,1,1,1],padding='SAME') #生成原始图 print_op_shape(t1_x_image)
四 合并还原结果,并使用TensorFlow输出
这次是将结果通过TensorBoard进行展示,所以将生成第一层图像和第二层图像与原始图像和在一起,统一放在tf.summary.image()里,这样在TensorBoard的image就可以看到图像了。
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

分类:
tensorflow
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了