python之tensorflow学习



目录

 

第一章Tensorflow的张量简单学习... 3

1.1tensorflow定义计算图和用会话执行计算... 3

1.2tensor张量理解... 5

1.3session(会话)的理解... 5

1.4、用张量、会话、计算图的简单示例... 5

第二章使用Tensorflow改变图像... 8

2.1图像预处理... 8

第三章、tensorflow实现卷积神经网络(CNN... 11

3.1CNN简介... 11

3.2风格迁移... 12

总结... 17

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第一章Tensorflow的张量简单学习

1.1tensorflow定义计算图和用会话执行计算

Tensor为张量,表明其数据结构;Flow就是“流”,体现其计算模型

tensorflow程序一般分为两个阶段:

1、定义计算图所有的计算

2、在session中执行计算

a、默认计算图以及如何查看一个运算所属的计算图(详情看computegraph.py):

importtensorflow as tf

a=tf.constant([1.0,2.0],name='a') # 定义一个常量使用tf.constant方法

b=tf.constant([1.0,2.0],name='b')

result =a+b

# 通过a.graph可以查看张量所属的计算图,如果没有特别指定,则属于当前默认的计算图

print(a.graphis tf.get_default_graph()) # 输出为True

btensorflow可以通过tf.Graph函数生成新的计算图。不同计算图上的张量和运算都不会共享(详情看different compute graph.py)

importtensorflow as tf

g1=tf.Graph()

withg1.as_default():

    # 在计算图g1中定义变量'v',并设置初始值为0

    v=tf.get_variable('v',initializer=tf.zeros_initializer()(shape= [1]))  

g2=tf.Graph()

withg2.as_default():

    # 在计算图g2中定义变量'v',并设置初始值微1

   v=tf.get_variable('v',initializer=tf.ones_initializer()(shape = [1]))

# 在计算图g1中读取变量'v'的取值

withtf.Session(graph=g1) as sess:

    tf.global_variables_initializer().run()

    with tf.variable_scope('',reuse=True):

        # 在计算图g1中,变量'v'的取值应该为0,下一行代码会输出[0.]

        print(sess.run(tf.get_variable('v')))

# 在计算图g2中读取变量'v'的取值

withtf.Session(graph=g2) as sess:

    tf.global_variables_initializer().run()

    with tf.variable_scope('',reuse=True):

        # 在计算图g2中,变量'v'的取值应该为1,下一行代码会输出[1.]

        print(sess.run(tf.get_variable('v')))

c、计算图可以通过tf.Graph.device函数来指定运行计算的设备,下面代码指定在GPU上运行加法计算(详情看graph device.py)

import tensorflow astf

a=tf.constant([1.0,2.0],name='a') # 定义一个常量使用tf.constant方法

b=tf.constant([1.0,2.0],name='b')

result = a+b

g=tf.Graph()

# 指定计算运行的设备。

withg.device('/gpu:0'):

    result=a+b

print(result)

d在一个计算图中,可以通过集合(collection)来管理不同类别的资源

通过tf.add_to_collection函数可以将资源加入到一个或多个集合中。

通过tf.get_collection获取集合里的资源。

Tensorflow也自动管理了一些常用的集合:如表所示

集合名称

集合内容 

使用场景

tf.GraphKeys.VARIABLES

所有变量

持久化tensorflow模型

tf.GraphKeys.TRAINABLE_VARIABLES

可学习的变量(一般指神经网络中的参数)

模型训练、生成模型可视化内容

tf.GraphKeys.SUMMARIES

日志生成相关的张量

tensorflow计算可视化

tf.GraphKeys.QUEUE_RUNNERS

处理输入的QueueRunner

输入处理

tf.GraphKeys.MOVING_AVERAGE_VARIABLES

所有计算了滑动平均值的变量

计算变量的滑动平均值

1.2tensor张量理解

张量可以简单理解为一个多维数组,其中0阶张量表示标量,即一个数,第一阶张量也就是一个一维数组,第n阶张量可以理解为一个n维数组。(详情看tensor.py

import tensorflow astf

# tf.constant是一个计算,这个计算的结果为一个张量,保存在变量a中。

a=tf.constant([1.0,2.0],name='a')#a赋值一个张量

b=tf.constant([1.0,2.0],name='b')#b赋值一个张量

result =tf.add(a,b,name='add')

print(result)

打印结果:

Tensor("add_18:0",shape=(2,), dtype=float32)

其中张量主要保存了三个属性:名字(name)、维度(shape)和类型(type)。

1.3session(会话)的理解

Session用来执行定义好的运算。tensorFlow使用session的方式有三种:

  • 明确调用会话生成函数和关闭会话函数

    sess=tf.Session()

    # 下面两个命令等价

    print(sess.run(result))

    print(result.eval(session=sess))

  • with生成一个默认会话

    sess=tf.Session()

    with sess.as_default():

       print(result.eval())

 

1.4、用张量、会话、计算图的简单示例

下面分别从定义二维张量、对数组求和、两个数组相乘、打印图片、生成裁剪图片

使用Tensorflow改变图像六个小程序来巩固上面对张量、计算图以及会话功能的掌握。

代码实现如下:

#定义二维张量

importnumpy as np

importtensorflow as tf

arr=np.array([(1,5.5,3,15,20),(10,20,30,40,50),(60,70,80,90,100)])#定义三维数组

tensor= tf.convert_to_tensor(arr)#将数组转换成张量

sess=tf.Session()#以第一种方式定义会话

print(sess.run(tensor))#打印

打印结果:

[[  1.   5.5   3.   15.  20. ]

 [ 10.  20.   30.   40.  50. ]

 [ 60.  70.   80.   90. 100. ]]

 

#对数组求和

importnumpy as np

importtensorflow as tf

#定义两个数组

arr1=np.array([(1,2,3),(4,5,6)])

arr2=np.array([(7,8,9),(10,11,12)])

#两个数组相加

arr3=tf.add(arr1,arr2)

sess=tf.Session()

tensor=sess.run(arr3)

print(tensor)

打印结果:

[[8 10 12]

 [14 16 18]]

 

#两个数组相乘

importnumpy as np

importtensorflow as tf

arr1=np.array([(1,2,3),(4,5,6)])

arr2=np.array([(7,8,9),(10,11,12)])

arr3=tf.multiply(arr1,arr2)

sess=tf.Session()

tensor=sess.run(arr3)

print(tensor)

打印结果:

[[7 16 27]

 [40 55 72]]

 

#打印图片

importmatplotlib.image as img

importmatplotlib.pyplot as plot

myfile= "sheep.jpg"

myimage=img.imread(myfile)

print(myimage.ndim)

print(myimage.shape)#宽度为150,高度为150,颜色深度为3

plot.imshow(myimage)

plot.show()

打印结果:

3

(194,259, 3)

 

#使用tensorflows生成裁剪图片

importtensorflow as tf

importmatplotlib.image as img

importmatplotlib.pyplot as plot

myfile="sheep.jpg"

myimage=img.imread(myfile)#读取图爿

slice= tf.placeholder("int32",[None,None,3])#生成图片

cropped=tf.slice(myimage,[100,0,0],[20,-1,-1])#裁剪图片

sess=tf.Session()

result=sess.run(cropped,feed_dict={slice:myimage})

plot.imshow(result)

plot.show()

 

打印结果

 

第二章使用Tensorflow改变图像

2.1图像预处理

图像预处理也可以用tensorflow来解决一些简单的图像的裁剪,上下旋转,左右旋转,图形的色调,对比度,亮度,以及手机上拍照的标注框等。下面以刘亦菲的图片作为简单示例进行代码演示。

#图像编码处理

import tensorflow as tf

import matplotlib.image as img

import matplotlib.pyplot as plot

#读取刘亦菲的照片

myimage=img.imread("yifei.jpg")

image=tf.Variable(myimage,name='image')

vars=tf.global_variables_initializer()

 

#创建会话

sess=tf.Session()

flipped=tf.transpose(image,perm=[1,0,2])

sess.run(vars)

#图像翻转

result=sess.run(flipped)

#打印矩阵

print(result)

plot.imshow(result)

plot.show()

#图像上下翻转

flipped1=tf.image.flip_up_down(myimage)

result1=sess.run(flipped1)

plot.imshow(result1)

plot.show()

#图像左右翻转

flipped2=tf.image.flip_left_right(myimage)

result2=sess.run(flipped2)

plot.imshow(result2)

plot.show()

#图像沿着对角线翻转

transposed=tf.image.transpose_image(myimage)

result3=sess.run(transposed)

plot.imshow(result3)

plot.show()

#图像调整亮度为-0.5(变暗)

adjusted=tf.image.adjust_brightness(myimage,-0.5)

result4=sess.run(adjusted)

plot.imshow(result4)

plot.show()

#图像调整亮度为+0.5(变亮)

adjusted1=tf.image.adjust_brightness(myimage,0.5)

result5=sess.run(adjusted1)

plot.imshow(result5)

plot.show()

#调整对比度

adjusted2=tf.image.adjust_contrast(myimage,-5)

result6=sess.run(adjusted2)

plot.imshow(result6)

plot.show()

#调整色相

adjusted3=tf.image.adjust_hue(myimage,0.3)

result7=sess.run(adjusted3)

plot.imshow(result7)

plot.show()

#调整饱和度

adjusted4=tf.image.adjust_saturation(myimage,3)

result8=sess.run(adjusted4)

plot.imshow(result8)

plot.show()

打印结果:

[[[214 213 229]

  [215 214 230]

  [216 215 231]

  ...

  [ 86  71  50]

  [ 88  73  52]

  [ 89  74 53]]

 

 [[214 213 229]

  [215 214 230]

  [216 215 231]

  ...

  [ 88  73  52]

  [ 88  76  54]

  [ 88  76 54]]

 

 [[215 214 230]

  [215 214 230]

  [216 215 231]

  ...

  [ 88  76  54]

  [ 89  77  55]

  [ 89  77 55]]

 

 ...

 

 [[206 205 223]

  [206 205 223]

  [206 205 223]

  ...

  [132 102  52]

  [131 101  51]

  [131 101  51]]

 

 [[206 205 223]

  [206 205 223]

  [206 205 223]

  ...

  [134 102  53]

  [134 102  53]

  [133 101  52]]

 

 [[206 205 223]

  [206 205 223]

  [206 205 223]

  ...

  [136 104  55]

  [135 103  54]

  [135 103  54]]]

 

第三章、tensorflow实现卷积神经网络(CNN

CNN是一个非常常用的神经网络模型,在图像识别领域、以及风格迁移有许多应用。

3.1CNN简介

卷积神经网络的基本结构图如下:

和全连接神经网络类似,CNN的每一个节点都是一个神经元;对于CNN,相邻两层之间的节点只有部分节点相连,为展示一层神经元的维度,每一层的卷积层的节点组织成一个三维矩阵。CNN的输入层为图像的原始像素,而输出层的每一个节点代表不同类别的可信度。

如上图所示,CNN主要由5种结构组成:

  1. 输入层:输入层为整个神经网络的输入,在处理CNN时,一般代表一张图片的像素矩阵

    其中,三维矩阵的长与宽表示了图像的大小,深度则表示了图像的色彩通道,比如黑白图片的深度为1RGB色彩模式下,图像的深度为3(由红、绿、蓝)组成。

    该层对原始图像做预处理:

    去均值:把输入数据各个维度都中心化为0
    归一化:幅度归一化到同样的范围,都变为相同的范围。

    白化:白化是对数据各个特征轴上的幅度归一化。

  2. 卷积层:此为CNN最重要部分。卷积层的每一个输入为上一层神经网络的亦小块,大小常用3*3或者5*5。可以改变深度。这个部分常被称作fitlerkernel。卷积层有几个神经元,depth深度就是多少;步长stride为窗口一次滑动的长度;

  3. 池化层:不会改变矩阵的深度,但是可压缩矩阵的大小,即可以将dpi高的转化为dpi低的。

  4. 全连接层:可以将卷积层和池化层看成特征提取的过程,之后依旧需要全连接层完成分类任务。

  5. Softmax层:主要用于分类,可以得到当前属于不同种类的概率分布情况。

     

    3.2风格迁移

     

    风格迁移值的是将图像A的风格转换到图像B中去,得到新的图像,取个名字为new B,其中new B中既包含图像B的内容,也包含图像A的风格。

    如输入原图片为:左边为背景图片,右边为内容图片(像素为水平800×高600)由于vgg-19层的模型文件较大,不作为上传。

    输出图片

     

    风格迁移示例代码(vgg-19自己去网上下载)

    importtensorflow as tf#导入tensorflow

    importnumpy as np#导入数值计算库

    importscipy.io#导入scipy

    importscipy.misc#导入数值计算库的misc

    importos#导入操作系统的接口库

     

    IMAGE_W= 800 #水平像素为800

    IMAGE_H= 600 #锤子像素为600

    CONTENT_IMG=  './images/yifei.jpg'#路径下的内容图片

    STYLE_IMG= './images/fengjing.jpg'#路径下的背景图片

    OUTOUT_DIR= './results'#输出路径下的结果图片

    OUTPUT_IMG= 'results.png'#输出图片

    VGG_MODEL= 'imagenet-vgg-verydeep-19.mat'#VGG_MODEL模型

    INI_NOISE_RATIO= 0.7#噪声比率

    STYLE_STRENGTH= 500#风格强度

    ITERATION= 5000#迭代次数

    CONTENT_LAYERS=[('conv4_2',1.)]#内容图片的卷积

    STYLE_LAYERS=[('conv1_1',1.),('conv2_1',1.),('conv3_1',1.),('conv4_1',1.),('conv5_1',1.)]#背景图片的卷积

     

    MEAN_VALUES= np.array([123, 117, 104]).reshape((1,1,1,3))#将三维矩阵转变为四维矩阵

    #建立神经网络的卷积池和池化池选择

    defbuild_net(ntype, nin, nwb=None):

      if ntype == 'conv':

        return tf.nn.relu(tf.nn.conv2d(nin, nwb[0],strides=[1, 1, 1, 1], padding='SAME')+ nwb[1])

      elif ntype == 'pool':

        return tf.nn.avg_pool(nin, ksize=[1, 2, 2,1],

                      strides=[1, 2, 2, 1],padding='SAME')

       

    #vgg的权重误差对比,返回权重和误差

    defget_weight_bias(vgg_layers, i,):

      weights = vgg_layers[i][0][0][0][0][0]

      weights = tf.constant(weights)

      bias = vgg_layers[i][0][0][0][0][1]

      bias = tf.constant(np.reshape(bias,(bias.size)))

      return weights, bias

    #19vgg模型进行定义

    defbuild_vgg19(path):

      net = {}

      vgg_rawnet = scipy.io.loadmat(path)

      vgg_layers = vgg_rawnet['layers'][0]

      #输入层

      net['input'] = tf.Variable(np.zeros((1,IMAGE_H, IMAGE_W, 3)).astype('float32'))

      #第一层卷积层×2

      net['conv1_1'] =build_net('conv',net['input'],get_weight_bias(vgg_layers,0))

      net['conv1_2'] =build_net('conv',net['conv1_1'],get_weight_bias(vgg_layers,2))

      #1层池化层×1

      net['pool1']  = build_net('pool',net['conv1_2'])

      #2层卷积层×2

      net['conv2_1'] =build_net('conv',net['pool1'],get_weight_bias(vgg_layers,5))

      net['conv2_2'] = build_net('conv',net['conv2_1'],get_weight_bias(vgg_layers,7))

      #2层池化层×1

      net['pool2']  = build_net('pool',net['conv2_2'])

    #3层卷积层×4

      net['conv3_1'] =build_net('conv',net['pool2'],get_weight_bias(vgg_layers,10))

      net['conv3_2'] =build_net('conv',net['conv3_1'],get_weight_bias(vgg_layers,12))

      net['conv3_3'] =build_net('conv',net['conv3_2'],get_weight_bias(vgg_layers,14))

      net['conv3_4'] =build_net('conv',net['conv3_3'],get_weight_bias(vgg_layers,16))

    #3层池化层×1

      net['pool3']  = build_net('pool',net['conv3_4'])

      #4层卷积层×4

      net['conv4_1'] =build_net('conv',net['pool3'],get_weight_bias(vgg_layers,19))

      net['conv4_2'] =build_net('conv',net['conv4_1'],get_weight_bias(vgg_layers,21))

      net['conv4_3'] =build_net('conv',net['conv4_2'],get_weight_bias(vgg_layers,23))

      net['conv4_4'] =build_net('conv',net['conv4_3'],get_weight_bias(vgg_layers,25))

      #4层池化层×1

      net['pool4']  = build_net('pool',net['conv4_4'])

      #5层卷积层×4

      net['conv5_1'] =build_net('conv',net['pool4'],get_weight_bias(vgg_layers,28))

      net['conv5_2'] =build_net('conv',net['conv5_1'],get_weight_bias(vgg_layers,30))

      net['conv5_3'] =build_net('conv',net['conv5_2'],get_weight_bias(vgg_layers,32))

      net['conv5_4'] =build_net('conv',net['conv5_3'],get_weight_bias(vgg_layers,34))

      #第五层池化层

      net['pool5']  = build_net('pool',net['conv5_4'])

      return net

     

    #建立内容损失值

    defbuild_content_loss(p, x):

      M = p.shape[1]*p.shape[2]

      N = p.shape[3]

      loss = (1./(2* N**0.5 * M**0.5 )) *tf.reduce_sum(tf.pow((x - p),2)) 

      return loss

     

    #得到最大矩阵

    defgram_matrix(x, area, depth):

      x1 = tf.reshape(x,(area,depth))

      g = tf.matmul(tf.transpose(x1), x1)

      return g

    #得到转置后的最大矩阵

    defgram_matrix_val(x, area, depth):

      x1 = x.reshape(area,depth)

      g = np.dot(x1.T, x1)

      return g

     

    #背景图片的损失

    defbuild_style_loss(a, x):

      M = a.shape[1]*a.shape[2]

      N = a.shape[3]

      A = gram_matrix_val(a, M, N )

      G = gram_matrix(x, M, N )

      loss = (1./(4 * N**2 * M**2)) *tf.reduce_sum(tf.pow((G - A),2))

      return loss

     

    #读取图片

    defread_image(path):

      image = scipy.misc.imread(path)

      image = scipy.misc.imresize(image,(IMAGE_H,IMAGE_W))

      image = image[np.newaxis,:,:,:]

      image = image - MEAN_VALUES

      return image

    #写入图片

    defwrite_image(path, image):

      image = image + MEAN_VALUES

      image = image[0]

      image = np.clip(image, 0, 255).astype('uint8')

      scipy.misc.imsave(path, image)

     

    #主函数定义

    defmain():

      net = build_vgg19(VGG_MODEL)

      sess = tf.Session()

      sess.run(tf.initialize_all_variables())

      noise_img = np.random.uniform(-20, 20, (1,IMAGE_H, IMAGE_W, 3)).astype('float32')

      content_img = read_image(CONTENT_IMG)

      style_img = read_image(STYLE_IMG)

     

      sess.run([net['input'].assign(content_img)])

      cost_content = sum(map(lambda l,:l[1]*build_content_loss(sess.run(net[l[0]]) , net[l[0]])

        , CONTENT_LAYERS))

     

      sess.run([net['input'].assign(style_img)])

      cost_style = sum(map(lambda l:l[1]*build_style_loss(sess.run(net[l[0]]) , net[l[0]])

        , STYLE_LAYERS))

     

      cost_total = cost_content + STYLE_STRENGTH *cost_style

      optimizer = tf.train.AdamOptimizer(2.0)

     

      train = optimizer.minimize(cost_total)

      sess.run(tf.initialize_all_variables())

      sess.run(net['input'].assign(INI_NOISE_RATIO* noise_img + (1.-INI_NOISE_RATIO) * content_img))

     

      if not os.path.exists(OUTOUT_DIR):

          os.mkdir(OUTOUT_DIR)

     

      for i in range(ITERATION):

        sess.run(train)

        if i%100 ==0:

          result_img = sess.run(net['input'])

          print( sess.run(cost_total))

         write_image(os.path.join(OUTOUT_DIR,'%s.png'%(str(i).zfill(4))),result_img)

     

     write_image(os.path.join(OUTOUT_DIR,OUTPUT_IMG),result_img)

     

     

    if__name__ == '__main__':

      main()

     

猜你喜欢

转载自blog.csdn.net/qq_16668303/article/details/80156988
今日推荐