威尼斯人网上投注基于CNN的遥感图像场景分类(一)

by admin on 2019年10月15日

由于专业及课题需要学习利用卷积神经网络的方法对头颅MRI影像进行病灶分割,想问问各位大神零基础的话需要学习哪些课程?谢谢

tensorflow升级到1.0之后,增加了一些高级模块: 如tf.layers, tf.metrics,
和tf.losses,使得代码稍微有些简化。

本文希望实现一个简单的卷积神经网络结构,用于遥感图像的场景分类
,作为在遥感数据上进行深度学习的入门实践

利用卷积神经网络训练图像数据分为以下几个步骤

在威尼斯人网上投注,https://zhuanlan.zhihu.com/p/27288913的基础上,重写了tf.Graph。

任务:花卉分类


  1. 读取图片文件
  2. 产生用于训练的批次
  3. 定义训练的模型(包括初始化参数,卷积、池化层等参数、网络)
  4. 训练
    global_step = tf.Variable(0, trainable=False)
    # placeholder
    images = tf.placeholder(tf.float32, [BATCH_SIZE, 32, 32, 3], name='images')
    labels = tf.placeholder(tf.int32, (BATCH_SIZE,), name='labels')

    print("Done Initializing Training Placeholders")

版本:tensorflow 1.0

此次实践的主要参考资料为Kevin Xu 的 Tensorflow tutorial: Cats vs.
dogs;在此表示感谢

1 读取图片文件

 1 def get_files(filename):
 2     class_train = []
 3     label_train = []
 4     for train_class in os.listdir(filename):
 5         for pic in os.listdir(filename+train_class):
 6             class_train.append(filename+train_class+'/'+pic)
 7             label_train.append(train_class)
 8     temp = np.array([class_train,label_train])
 9     temp = temp.transpose()
10     #shuffle the samples
11     np.random.shuffle(temp)
12     #after transpose, images is in dimension 0 and label in dimension 1
13     image_list = list(temp[:,0])
14     label_list = list(temp[:,1])
15     label_list = [int(i) for i in label_list]
16     #print(label_list)
17     return image_list,label_list

  这里文件名作为标签,即类别(其数据类型要确定,后面要转为tensor类型数据)。

  然后将image和label转为list格式数据,因为后边用到的的一些tensorflow函数接收的是list格式数据。

labels不是one-hot模式,就是数字本身。
placeholder的第一维都是固定的batch_size。

数据:flower-photos.rar)

源码地址:GitHub
视频教程:
YouTube

2 产生用于训练的批次

 1 def get_batches(image,label,resize_w,resize_h,batch_size,capacity):
 2     #convert the list of images and labels to tensor
 3     image = tf.cast(image,tf.string)
 4     label = tf.cast(label,tf.int64)
 5     queue = tf.train.slice_input_producer([image,label])
 6     label = queue[1]
 7     image_c = tf.read_file(queue[0])
 8     image = tf.image.decode_jpeg(image_c,channels = 3)
 9     #resize
10     image = tf.image.resize_image_with_crop_or_pad(image,resize_w,resize_h)
11     #(x - mean) / adjusted_stddev
12     image = tf.image.per_image_standardization(image)
13     
14     image_batch,label_batch = tf.train.batch([image,label],
15                                              batch_size = batch_size,
16                                              num_threads = 64,
17                                              capacity = capacity)
18     images_batch = tf.cast(image_batch,tf.float32)
19     labels_batch = tf.reshape(label_batch,[batch_size])
20     return images_batch,labels_batch

  首先使用tf.cast转化为tensorflow数据格式,使用tf.train.slice_input_producer实现一个输入的队列。

  label不需要处理,image存储的是路径,需要读取为图片,接下来的几步就是读取路径转为图片,用于训练。

  CNN对图像大小是敏感的,第10行图片resize处理为大小一致,12行将其标准化,即减去所有图片的均值,方便训练。

  接下来使用tf.train.batch函数产生训练的批次。

  最后将产生的批次做数据类型的转换和shape的处理即可产生用于训练的批次。

    # Build a Graph that computes the logits predictions from the placeholder
    logits = CNN(images)

    # Calculate loss
    loss = cal_loss(logits, labels)

    # Build a Graph that trains the model with one batch of examples and
    # updates the model parameters.
    train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

花总共有五类,分别放在5个文件夹下。

原教程中,采用的是Kaggle
的猫狗大战的竞赛数据,有两万多张猫狗的数据集,实际上是个二分类的问题,作为深度学习的入门再合适不过。本文希望学习这个实战课程并获得以下两个知识:

3 定义训练的模型

logits的shape是(batch_size,10),是one-hot形式
cal_loss中,Logits的shape是(batch_size,10),而labels则是(batch_size,1),因此用的函数是tf.nn.sparse_softmax_cross_entropy_with_logits

闲话不多说,直接上代码,希望大家能看懂:)

  • 自制数据集的读取
  • 简单网络结构的搭建和训练

(1)训练参数的定义及初始化

 

 1 def init_weights(shape):
 2     return tf.Variable(tf.random_normal(shape,stddev = 0.01))
 3 #init weights
 4 weights = {
 5     "w1":init_weights([3,3,3,16]),
 6     "w2":init_weights([3,3,16,128]),
 7     "w3":init_weights([3,3,128,256]),
 8     "w4":init_weights([4096,4096]),
 9     "wo":init_weights([4096,2])
10     }
11 
12 #init biases
13 biases = {
14     "b1":init_weights([16]),
15     "b2":init_weights([128]),
16     "b3":init_weights([256]),
17     "b4":init_weights([4096]),
18     "bo":init_weights([2])
19     }

 

  CNN的每层是y=wx+b的决策模型,卷积层产生特征向量,根据这些特征向量带入x进行计算,因此,需要定义卷积层的初始化参数,包括权重和偏置。其中第8行的参数形状后边再解释。

训练部分:

复制代码

从文件中读取数据

一个典型的文静读取管线包括下面几个步骤
1.文件名列表
2.可配置文件的文件名乱序(shuffling)
3.可配置文件最大训练迭代次数(epoch limit)
4.文件名队列
5.针对输入文件格式的阅读器
6.记录解析器
7.可配置的预处理器
8.样本队列

依据代码来理解上面的几个步骤
首先我们通过一个函数get_files来获取文件列表
这个文件列表是从你的训练集中进行读取,首先这个训练集应该包含了所有的训练样本图片,图片的命名规则按照图片所属的类别进行标注。本例子中

import tensorflow as tf
import numpy as np
import os

def get_files(file_dir):

 (2)定义不同层的操作

 1 def conv2d(x,w,b):
 2     x = tf.nn.conv2d(x,w,strides = [1,1,1,1],padding = "SAME")
 3     x = tf.nn.bias_add(x,b)
 4     return tf.nn.relu(x)
 5 
 6 def pooling(x):
 7     return tf.nn.max_pool(x,ksize = [1,2,2,1],strides = [1,2,2,1],padding = "SAME")
 8 
 9 def norm(x,lsize = 4):
10     return tf.nn.lrn(x,depth_radius = lsize,bias = 1,alpha = 0.001/9.0,beta = 0.75)

  这里只定义了三种层,即卷积层、池化层和正则化层

    for step in range(1000):
        # Current batch number
        batch_nb = step % nb_batches

        # Current batch start and end indices
        start, end = utils.batch_indices(batch_nb, data_length, BATCH_SIZE)

        # Prepare dictionnary to feed the session with
        feed_dict = {images: X_train[start:end],
                     labels: y_train[start:end]}

        # Run training step
        _, loss_value = sess.run([train_step, loss], feed_dict=feed_dict)

        # Echo loss once in a while
        if step % 20 == 0:
            num_examples_per_step = BATCH_SIZE
            examples_per_sec = num_examples_per_step / duration
            sec_per_batch = float(duration)

            format_str = ('%s: step %d, loss = %.2f (%.1f examples/sec; %.3f '
                          'sec/batch)')
            print(format_str % (datetime.now(), step, loss_value,
                                examples_per_sec, sec_per_batch))
# -*- coding: utf-8 -*-

from skimage import io,transform
import glob
import os
import tensorflow as tf
import numpy as np
import time

path='e:/flower/'

#将所有的图片resize成100*100
w=100
h=100
c=3


#读取图片
def read_img(path):
 cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)]
 imgs=[]
 labels=[]
 for idx,folder in enumerate(cate):
  for im in glob.glob(folder+'/*.jpg'):
   print('reading the images:%s'%(im))
   img=io.imread(im)
   img=transform.resize(img,(w,h))
   imgs.append(img)
   labels.append(idx)
 return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
data,label=read_img(path)


#打乱顺序
num_example=data.shape[0]
arr=np.arange(num_example)
np.random.shuffle(arr)
data=data[arr]
label=label[arr]


#将所有数据分为训练集和验证集
ratio=0.8
s=np.int(num_example*ratio)
x_train=data[:s]
y_train=label[:s]
x_val=data[s:]
y_val=label[s:]

#-----------------构建网络----------------------
#占位符
x=tf.placeholder(tf.float32,shape=[None,w,h,c],name='x')
y_=tf.placeholder(tf.int32,shape=[None,],name='y_')

#第一个卷积层(100——>50)
conv1=tf.layers.conv2d(
  inputs=x,
  filters=32,
  kernel_size=[5, 5],
  padding="same",
  activation=tf.nn.relu,
  kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool1=tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

#第二个卷积层(50->25)
conv2=tf.layers.conv2d(
  inputs=pool1,
  filters=64,
  kernel_size=[5, 5],
  padding="same",
  activation=tf.nn.relu,
  kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool2=tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

#第三个卷积层(25->12)
conv3=tf.layers.conv2d(
  inputs=pool2,
  filters=128,
  kernel_size=[3, 3],
  padding="same",
  activation=tf.nn.relu,
  kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool3=tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2)

#第四个卷积层(12->6)
conv4=tf.layers.conv2d(
  inputs=pool3,
  filters=128,
  kernel_size=[3, 3],
  padding="same",
  activation=tf.nn.relu,
  kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
pool4=tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2)

re1 = tf.reshape(pool4, [-1, 6 * 6 * 128])

#全连接层
dense1 = tf.layers.dense(inputs=re1, 
      units=1024, 
      activation=tf.nn.relu,
      kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
      kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
dense2= tf.layers.dense(inputs=dense1, 
      units=512, 
      activation=tf.nn.relu,
      kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
      kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
logits= tf.layers.dense(inputs=dense2, 
      units=5, 
      activation=None,
      kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
      kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))
#---------------------------网络结束---------------------------

loss=tf.losses.sparse_softmax_cross_entropy(labels=y_,logits=logits)
train_op=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_) 
acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


#定义一个函数,按批次取数据
def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
 assert len(inputs) == len(targets)
 if shuffle:
  indices = np.arange(len(inputs))
  np.random.shuffle(indices)
 for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
  if shuffle:
   excerpt = indices[start_idx:start_idx + batch_size]
  else:
   excerpt = slice(start_idx, start_idx + batch_size)
  yield inputs[excerpt], targets[excerpt]


#训练和测试数据,可将n_epoch设置更大一些

n_epoch=10
batch_size=64
sess=tf.InteractiveSession() 
sess.run(tf.global_variables_initializer())
for epoch in range(n_epoch):
 start_time = time.time()

 #training
 train_loss, train_acc, n_batch = 0, 0, 0
 for x_train_a, y_train_a in minibatches(x_train, y_train, batch_size, shuffle=True):
  _,err,ac=sess.run([train_op,loss,acc], feed_dict={x: x_train_a, y_: y_train_a})
  train_loss += err; train_acc += ac; n_batch += 1
 print(" train loss: %f" % (train_loss/ n_batch))
 print(" train acc: %f" % (train_acc/ n_batch))

 #validation
 val_loss, val_acc, n_batch = 0, 0, 0
 for x_val_a, y_val_a in minibatches(x_val, y_val, batch_size, shuffle=False):
  err, ac = sess.run([loss,acc], feed_dict={x: x_val_a, y_: y_val_a})
  val_loss += err; val_acc += ac; n_batch += 1
 print(" validation loss: %f" % (val_loss/ n_batch))
 print(" validation acc: %f" % (val_acc/ n_batch))

sess.close()

 (3)定义训练模型

 1 def mmodel(images):
 2     l1 = conv2d(images,weights["w1"],biases["b1"])
 3     l2 = pooling(l1)
 4     l2 = norm(l2)
 5     l3 = conv2d(l2,weights["w2"],biases["b2"])
 6     l4 = pooling(l3)
 7     l4 = norm(l4)
 8     l5 = conv2d(l4,weights["w3"],biases["b3"])
 9     #same as the batch size
10     l6 = pooling(l5)
11     l6 = tf.reshape(l6,[-1,weights["w4"].get_shape().as_list()[0]])
12     l7 = tf.nn.relu(tf.matmul(l6,weights["w4"])+biases["b4"])
13     soft_max = tf.add(tf.matmul(l7,weights["wo"]),biases["bo"])
14     return soft_max

  模型比较简单,使用三层卷积,第11行使用全连接,需要对特征向量进行reshape,其中l6的形状为[-1,w4的第1维的参数],因此,将其按照“w4”reshape的时候,要使得-1位置的大小为batch_size,这样,最终再乘以“wo”时,最终的输出大小为[batch_size,class_num]

检测部分:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

(4)定义评估量

1 def loss(logits,label_batches):
2     cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits,labels=label_batches)
3     cost = tf.reduce_mean(cross_entropy)
4     return cost

  首先定义损失函数,这是用于训练最小化损失的必需量

1 def get_accuracy(logits,labels):
2     acc = tf.nn.in_top_k(logits,labels,1)
3     acc = tf.cast(acc,tf.float32)
4     acc = tf.reduce_mean(acc)
5     return acc

  评价分类准确率的量,训练时,需要loss值减小,准确率增加,这样的训练才是收敛的。

newbatch = math.ceil(1000 / BATCH_SIZE)
preds = np.zeros((1000, NUM_CLASS), dtype=np.float32)
# 检测数据有1000,分为64大小的部分循环检测
for cnt in range(0, int(newbatch + 1)):
      # Compute batch start and end indices
      start, end = utils.batch_indices(cnt, 1000, BATCH_SIZE)
      # Prepare feed dictionary
      feed_dict = {images: X_test[start:end]}
      preds[start:end, :] = sess.run([logits], feed_dict=feed_dict)[0]#取第一维

precision = accuracy(preds, y_test)
print('Precision of teacher after training: ' + str(precision))

您可能感兴趣的文章:

  • 详解tensorflow训练自己的数据集实现CNN图像分类
  • Python爬取京东的商品分类与链接
  • Python使用bs4获取58同城城市分类的方法
  • Python实现自动为照片添加日期并分类的方法
  • Python决策树分类算法学习

(5)定义训练方式

1 def training(loss,lr):
2     train_op = tf.train.RMSPropOptimizer(lr,0.9).minimize(loss)
3     return train_op

  有很多种训练方式,可以自行去官网查看,但是不同的训练方式可能对应前面的参数定义不一样,需要另行处理,否则可能报错。

训练步长设置为0.1,正确率达到60%
训练步长设置为0.05,正确率达到65%
链接:https://github.com/yingtaomj/cnn-classification

 4 训练

 1 def run_training():
 2     data_dir = 'C:/Users/wk/Desktop/bky/dataSet/'
 3     image,label = inputData.get_files(data_dir)
 4     image_batches,label_batches = inputData.get_batches(image,label,32,32,16,20)
 5     p = model.mmodel(image_batches)
 6     cost = model.loss(p,label_batches)
 7     train_op = model.training(cost,0.001)
 8     acc = model.get_accuracy(p,label_batches)
 9     
10     sess = tf.Session()
11     init = tf.global_variables_initializer()
12     sess.run(init)
13     
14     coord = tf.train.Coordinator()
15     threads = tf.train.start_queue_runners(sess = sess,coord = coord)
16     
17     try:
18        for step in np.arange(1000):
19            print(step)
20            if coord.should_stop():
21                break
22            _,train_acc,train_loss = sess.run([train_op,acc,cost])
23            print("loss:{} accuracy:{}".format(train_loss,train_acc))
24     except tf.errors.OutOfRangeError:
25         print("Done!!!")
26     finally:
27         coord.request_stop()
28     coord.join(threads)
29     sess.close()

  

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图