tensorflow下的图片标准化函数per_image_standardization用法

更新时间:2023-07-18 02:35:53 阅读: 评论:0

tensorflow下的图⽚标准化函数
per_image_standardization⽤法
实验环境:windows 7,anaconda 3(Python 3.5),tensorflow(gpu/cpu)
函数介绍:标准化处理可以使得不同的特征具有相同的尺度(Scale)。
这样,在使⽤梯度下降法学习参数的时候,不同特征对参数的影响程度就⼀样了。
tf.image.per_image_standardization(image),此函数的运算过程是将整幅图⽚标准化(不是归⼀化),加速神经⽹络的训练。
主要有如下操作,(x - mean) / adjusted_stddev,其中x为图⽚的RGB三通道像素值,mean分别为三通道像素的均
值,adjusted_stddev = max(stddev, 1.0/sqrt(image.NumElements()))。
stddev为三通道像素的标准差,image.NumElements()计算的是三通道各⾃的像素个数。
实验代码:
import tensorflow as tf
import matplotlib.image as img
import matplotlib.pyplot as plt
import numpy as np
ss = tf.InteractiveSession()
image = img.imread('D:/Documents/Pictures/logo7.jpg')
shape = tf.shape(image).eval()
描述春天h,w = shape[0],shape[1]
standardization_image = tf.image.per_image_standardization(image)#标准化
fig = plt.figure()
fig1 = plt.figure()
ax = fig.add_subplot(111)
ax.t_title('orginal image')
ax.imshow(image)
ax1 = fig1.add_subplot(311)
ax1.t_title('original hist')
ax1.hist(ss.shape(image,[h*w,-1])))
ax1 = fig1.add_subplot(313)
ax1.t_title('standardization hist')
ax1.hist(ss.shape(standardization_image,[h*w,-1])))
plt.ion()
plt.show()
实验结果:
两幅hist图分别是原图和标准化后的RGB的像素值分布图,可以看到只是将图⽚的像素值⼤⼩限定到⼀个范围,但是像素值的分布为改变。
补充知识:tensorflow运⾏单张图像与加载模型时注意的问题
关于模型的保存加载:
在做实验的情况下,⼀般使⽤save函数与restore函数就⾜够⽤,该刚发只加载模型的参数⽽不加载模型,这意味着当前的程序要能找到模型的结构
saver = tf.train.Saver()#声明saver⽤来保存模型
with tf.Session() as ss:
for i in range(train_step):
#.....训练操作
if i%100 == 0 && i!= 0:#每间隔训练100次存储⼀个模型,默认最多能存5个,如果超过5个先将序号⼩
的覆盖掉
saver.save(ss,str(i)+"_"+'model.ckpt',global_step=i)
拍身份证照片能化妆吗得到的⽂件如下:
在⼀个⽂件夹中,会有⼀个checkpoint⽂件,以及⼀系列不同训练阶段的模型⽂件,如下图
ckeckpoint⽂件可以放在编辑器⾥⾯打开看,⾥⾯记录的是每个阶段保存模型的信息,同时也是记录最近训练的检查点
保和颗粒的功效与作用>双子男和天蝎女
ckpt⽂件是模型参数,index⽂件⼀般⽤不到(我也查到是啥-_-|||)
在读取模型时,声明⼀个saver调⽤restore函数即可,我看很多博客⾥⾯写的都是添加最近检查点的模型,这样添加的模型都是最后⼀次训练的结果,想要加载固定的模型,直接把模型参数名称的字符串写到参数⾥就⾏了,如下段程序
saver = tf.train.Saver()
with tf.Session() as ss:
这样就把参数加载到Session当中,如果有数据,就可以直接塞进来进⾏计算了
运⾏单张图⽚:
运⾏单张图像的⽅法的流程⼤致如下,⾸先使⽤opencv或者Image或者使⽤numpy将图像读进来,保存成numpy的array的格式
接下来可以对图像使⽤opencv进⾏预处理。然后将处理后的array使⽤feed_dict的⽅式输⼊到tensorflow的placeholder中,这⾥注意两点,不要单独的使⽤下⾯的⽅法将tensor转换成numpy再进⾏处理,除⾮是想查看⼀下图像输出,否则在验证阶段,强烈不要求这样做,尽量使⽤feed_dict,原因后⾯说明
numpy_img = ss.run(tensor_img)#将tensor转换成numpy
这⾥注意⼀点,如果你的图像是1通道的图像,即灰度图,那么你得到的numpy是⼀个⼆维矩阵,将使⽤opencv读⼊的图像输出shape会得到如(424,512)这样的形状,分别表⽰⾏和列,但是在模型当中通常要要有batch和通道数,所以需要将图像使⽤python opencv库中的reshape函数转换成四维的矩阵,如
cv_img = shape(1,cv_img.shape[0],cv_img.shape[1],1)#cv_img是使⽤Opencv读进来的图⽚
⽤来输⼊到⽹络中的placeholder设置为如下,即可进⾏输⼊了
img_raw = tf.placeholder(dtype=tf.float32, shape=[1,512, 424, 1], name='input')
测试:
如果使⽤的是⾃⼰的数据集,通常是制作成tfrecords,在训练和测试的过程中,需要读取tfrecords⽂件,这⾥注意,千万不要把读取tfrecords⽂件的函数放到循环当中,⽽是把这个⽂件放到外⾯,否则你训练或者测试的数据都是同⼀批,Loss会固定在⼀个值!
美女穿比基尼照片这是因为tfrecords在读取的过程中是将图像信息加⼊到⼀个队列中进⾏读取,不要当成普通的函数调⽤,要按照tensorflow的思路,将它看成⼀个节点!
def read_data(tfrecords_file, batch_size, image_size):#读取tfrecords⽂件
让爱飞扬
filename_queue = tf.train.string_input_producer([tfrecords_file])
reader = tf.TFRecordReader()
_, rialized_example = ad(filename_queue)
img_features = tf.par_single_example(
rialized_example,
features={
'label': tf.FixedLenFeature([], tf.int64),
'image_raw': tf.FixedLenFeature([], tf.string),
})
image = tf.decode_raw(img_features['image_raw'], tf.float32)
min_after_dequeue = 1000
image = tf.reshape(image, [image_size, image_size,1])
image = size_images(image, (32,32),method=3)#缩放成32×32
image = tf.image.per_image_standardization(image)#图像标准化
label = tf.cast(img_features['label'], tf.int32)
capacity = min_after_dequeue + 3 * batch_size
image_batch, label_batch = tf.train.shuffle_batch([image, label],
min_after_dequeue = min_after_dequeue)
return image_batch, tf.one_hot(label_batch,6)#返回的标签经过one_hot编码
#将得到的图像数据与标签都是tensor哦,不能输出的!
read_image_batch,read_label_batch = read_data('train_data\\tfrecord\\TrainC6_95972.tfrecords',batch_size,120)
回到在运⾏单张图⽚的那个问题,直接对某个tensor进⾏ss.run()会得到图计算后的类型,也就是咱们python中常见的类型。
使⽤ss.run(feed_dict={…})得到的计算结果和直接使⽤ss.run有什么不同呢?
可以使⽤⼀个循环实验⼀下,在循环中不停的调⽤ss.run()相当于每次都向图中添加节点,⽽使⽤ss.run(feed_dict={})是向图中开始的位置添加数据!
结果会发现,直接使⽤ss.run()的运⾏会越来越慢,使⽤ss.run(feed_dict={})会运⾏的飞快!
为什么要提这个呢?
在上⾯的read_data中有这么三⾏函数
image = tf.reshape(image, [image_size, image_size,1])#与opencv的reshape结果⼀样
image = size_images(image, (32,32),method=3)#缩放成32×32,与opencv的resize结果⼀样,插值⽅法要选择三次⽴⽅插值
image = tf.image.per_image_standardization(image)#图像标准化
如果想要在将训练好的模型作为⽹络节点添加到系统中,得到的数据必须是经过与训练数据经过相同处理的图像,也就是必须要对原始图像经过上⾯的处理。如果使⽤其他的库容易造成结果对不上,最好使⽤与训练数据处理时相同的函数。
如果使⽤将上⾯的函数当成普通的函数使⽤,得到的是⼀个tensor,没有办法进⾏其他的图像预处理,需要先将tensor变成numpy类型,问题来了,想要变成numpy类型,就得调⽤ss.run(),如果模型作为接⼝死循环,那么就会⼀直使⽤
结膜炎
ss.run,效率会越来越慢,最后卡死!
原因在于你没有将tensorflow中的函数当成节点调⽤,⽽是将其当成普通的函数调⽤了!
解决办法就是按部就班的来,将得到的numpy数据先提前处理好,然后使⽤ss.run(feed_dict)输⼊到placeholder中,按照图的顺序⼀步⼀步运⾏即可!
如下⾯程序
with tf.name_scope('inputs'):
img_raw = tf.placeholder(dtype=tf.float32, shape=[1,120, 120, 1], name='input')#输⼊数据
keep_prob = tf.placeholder(tf.float32,name='keep_prob')
with tf.name_scope('preprocess'):#图中的预处理函数,当成节点顺序调⽤
img_120 = tf.reshape(img_raw, [120, 120,1])
img_norm = tf.cast(img_120, "float32") / 256
img_32 = size_images(img_norm, (32,32),method=3)
img_std = tf.image.per_image_standardization(img_32)
img = tf.reshape(img_std, [1,32, 32,1])
with tf.name_scope('output'):#图像塞到⽹络中
output = MyNet(img,keep_prob,n_cls)
ans = tf.softmax(output),1)#计算模型得到的结果
init = tf.global_variables_initializer()
saver = tf.train.Saver()
if __name__ == '__main__':
with tf.Session() as ss:
ss.run(init)新疆图书馆
index = 0
path = "buffer\\"
while True:
f = path + str(index)+'.jpg'#从0.jpg、1.jpg、⼀直读
if ists(f):
cv_img = cv.imread(f,0)
cv_img = OneImgPrepro(cv_img)
cv_img = shape(1,cv_img.shape[0],cv_img.shape[1],1)#需要reshape成placeholder可接收型
clas = ans.eval(feed_dict={img_raw:cv_img,keep_prob:1})#feed的速度快!
print(clas)#输出分类
index += 1
以上这篇tensorflow下的图⽚标准化函数per_image_standardization⽤法就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

本文发布于:2023-07-18 02:35:53,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1085801.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:模型   图像   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图