开发者社区  >  开发问答  >  课程讨论 · TensorFlow中级教程

课程讨论 · TensorFlow中级教程

如题

相关回答 

普陀 1年前 26声望

Cifar10_Cifar100_数据读取及CNN测试

cifar_input.py

"""Routine for decoding the CIFAR-10 binary file format."""

import os
import sys
import numpy as np
import tarfile #解压文件
from six.moves import urllib
from six.moves import xrange
import tensorflow as tf

# 用于描述CiFar数据集的全局变量
IMAGE_SIZE = 32  # 数据 height=width=IMAGE_SIZE
IMAGE_DEPTH = 3 # 数据通道
NUM_CLASSES_CIFAR10 = 10 # CiFar10 数据,10分类
NUM_CLASSES_CIFAR20 = 20  # CiFar100 数据,粗分类,20类,coarse label
NUM_CLASSES_CIFAR100 = 100 # CiFar100 数据,细分类,100类 , fine label

NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 50000 # TRAIN data
NUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 10000 # EVAL data

# 从网站上下载数据集存放到 data_dir 指定的目录下
CIFAR10_DATA_URL = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'
CIFAR100_DATA_URL = 'http://www.cs.toronto.edu/~kriz/cifar-100-binary.tar.gz'


def maybe_download_and_extract(data_dir, data_url=CIFAR10_DATA_URL):
    dest_directory  = data_dir  # 存放数据目录
    DATA_URL = data_url
    # 判断是否存在,不存在就创建,
    if not os.path.exists(dest_directory):
        os.makedirs(dest_directory)
    filename = DATA_URL.split('/')[-1]
    filepath = os.path.join(dest_directory,filename)
    # 判断数据是否已经存在,否则执行下载
    if not os.path.exists(filepath):
        def _progress(count,block_size,total_size):
            sys.stdout.write('\r>>Downloading %s %.1f%%'%(filename,
                                                          float(count*block_size)/float(total_size)*100.0))
            sys.stdout.flush()
        filepath,_ = urllib.request.urlretrieve(DATA_URL,filepath,_progress)
        print()
        statinfo = os.stat(filepath)
        print('Successfully down loaded',filename,statinfo.st_size,'bytes.')
    # 将下载下来的压缩文件解压缩
    tarfile.open(filepath,'r:gz').extractall(dest_directory)


def read_cifar10(filename_queue, coarse_or_fine=None):

    # 定义类,为记录类,一个记录表示一张图像
    class CIFAR10Record(object):
        pass
    result = CIFAR10Record()

    # Dimensions of the images in the CIFAR-10 dataset.
    # input format.
    result.height = 32
    result.width = 32
    result.depth = 3

    # cifar10 binary 中的样本记录
    #  <1 x label><3072 x pixel>
    #         .......
    #  <1 x label><3072 x pixel>

    # label 标签字节数
    label_bytes = 1

    # 图像字节数
    image_bytes = result.height * result.width * result.depth
    # 每一条样本记录由 标签+图像 组成, 其字节数是固定的,3073
    record_bytes = label_bytes + image_bytes

    # 读取器,创建一个固定长度记录读取器,读取一个样本记录的所有字节 (label_bytes+image_bytes)
    # 由于 cifar10 中的记录没有 header_bytes 和 footer_bytes, 所以头字节与尾字节设置为0
    reader = tf.FixedLengthRecordReader(record_bytes=record_bytes, header_bytes=0, footer_bytes=0)
    # 调用读取器对象的 read 方法返回一条记录,
    # result.key, value样本在整体样本中的位置; value,样本中的字节码
    result.key, value = reader.read(filename_queue)

    # 将一个字节组成的 string 类别的记录转换为长度为 record_bytes, 类型为 uint8 的一个数字向量
    record_bytes = tf.decode_raw(value, tf.uint8)

    # 取标签,第一个字节代表了标签, 我们把他从 uint8 转换为 int32
    result.label = tf.cast(
        tf.strided_slice(record_bytes, [0], [label_bytes]), tf.int32) # [0, label_bytes]

    # 取图像数据,剩余的所有字节都是图像数据, 把他从一维张量 [depth * height * width]
    # 转为三维张量 [ depth, height, width]
    depth_major = tf.reshape(tf.strided_slice(record_bytes, [label_bytes], [label_bytes+image_bytes]), # [label_bytes, image_bytes]
                           [result.depth, result.height, result.width])
    # 把图像的空间位置和深度位置顺序由 [depth, height, width] 转换成 [height, width, depth].
    result.uint8image = tf.transpose(depth_major, [1, 2, 0])

    return result


def read_cifar100(filename_queue, coarse_or_fine='fine'):

    # 定义类,为记录类,一个记录表示一张图像
    class CIFAR100Record(object):
        pass
    result = CIFAR100Record()

    # Dimensions of the images in the CIFAR-10 dataset.
    # input format.
    result.height = 32
    result.width = 32
    result.depth = 3

    # cifar100 binary 中的样本记录
    # Cifar100 中每个样本记录都有两个类别标签,
    # 第一个字节是粗略分类标签,第二个字节是精细分类标签:

    #  <1 x coarse label><1 x fine label><3072 x pixel>
    #         .......
    #  <1 x coarse label><1 x fine label><3072 x pixel>

    # label 标签字节数
    coarse_label_bytes = 1
    fine_label_bytes = 1

    # 图像字节数
    image_bytes = result.height * result.width * result.depth
    # 每一条样本记录由 粗标签+细标签+图像 组成, 其字节数是固定的,3074
    record_bytes = coarse_label_bytes + fine_label_bytes + image_bytes

    # 读取器,创建一个固定长度记录读取器,读取一个样本记录的所有字节 (label_bytes+image_bytes)
    # 由于 cifar10 中的记录没有 header_bytes 和 footer_bytes, 所以头字节与尾字节设置为0
    reader = tf.FixedLengthRecordReader(record_bytes=record_bytes, header_bytes=0, footer_bytes=0)
    # 调用读取器对象的 read 方法返回一条记录,
    # result.key, value样本在整体样本中的位置; value,样本中的字节码
    result.key, value = reader.read(filename_queue)

    # 将一个字节组成的 string 类别的记录转换为长度为 record_bytes, 类型为 uint8 的一个数字向量
    record_bytes = tf.decode_raw(value, tf.uint8)

    # 取粗分类标签,第一个字节代表了粗分类标签, 我们把他从 uint8 转换为 int32
    coarse_label = tf.cast(
        tf.strided_slice(record_bytes, [0], [coarse_label_bytes]), tf.int32) # [0, label_bytes]
    # 取细分类标签,第二个字节代表了细分类标签, 我们把他从 uint8 转换为 int32
    fine_label = tf.cast(
        tf.strided_slice(record_bytes, [coarse_label_bytes], [coarse_label_bytes+fine_label_bytes]), tf.int32)

    if coarse_or_fine == 'fine':
        result.label = fine_label # 细分类标签,100类别
    else:
        result.label = coarse_label  # 粗分类标签,20类别

    # 取图像数据,剩余的所有字节都是图像数据, 把他从一维张量 [depth * height * width]
    # 转为三维张量 [ depth, height, width]
    depth_major = tf.reshape(
        tf.strided_slice(record_bytes,
                         [coarse_label_bytes+fine_label_bytes],
                         [coarse_label_bytes+fine_label_bytes+image_bytes]),
        [result.depth, result.height, result.width])
    # 把图像的空间位置和深度位置顺序由 [depth, height, width] 转换成 [height, width, depth].32*32*3
    result.uint8image = tf.transpose(depth_major, [1, 2, 0])

    return result


def _generate_image_and_label_batch(image, label, min_queue_examples,
                                    batch_size,shuffle):
  """Construct a queued batch of images and labels.

  Args:
    image: 3-D Tensor of [height, width, 3] of type.float32.
    label: 1-D Tensor of type.int32
    min_queue_examples: int32, minimum number of samples to retain
      in the queue that provides of batches of examples.
    batch_size: Number of images per batch.
    shuffle: boolean indicating whether to use a shuffling queue
  Returns:
    images: Images. 4D tensor of [batch_size, height, width, 3] size.
    labels: Labels. 1D tensor of [batch_size] size.
  """
  # Create a queue that shuffles the examples, and then
  # read 'batch_size' images + labels from the example queue.
  num_preprocess_threads = 16  # 并发执行线程
  if shuffle:
      images, label_batch = tf.train.shuffle_batch(
          [image, label],
          batch_size=batch_size,
          num_threads=num_preprocess_threads,
          capacity=min_queue_examples + 3 * batch_size,
          min_after_dequeue=min_queue_examples)
  else:
      images, label_batch = tf.train.batch(
          [image, label],
          batch_size=batch_size,
          num_threads=num_preprocess_threads,
          capacity=min_queue_examples + 3 * batch_size,)

  # Display the training images in the visualizer.
  # tf.summary.image('images', images, max_outputs=9)

  return images, tf.reshape(label_batch, [batch_size])


def distorted_inputs(cifar10or20or100, data_dir, batch_size):
    # 数据处理,扩充数据集
    """
    使用 Reader ops 构造 distorted input 用于 CIFAR 的训练
    输入参数:
    cifar10or20or100: 指定要读取的数据集是 cifar10 还是细分类 cifar100 或者粗分类 cifar100
    data_dir: 指向 CIFAR-10 或者 CIFAR-100 数据集的目录
    batch_size: 单个批次的图像数量
    :return: images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size
             labels: Labels. 1D tensor of [batch_size] size
    """
    # 判断是读取 cifar10 还是 cifar100 (cifar100又分20粗分类或者100细分类)
    if cifar10or20or100 == 10:
        filenames = [os.path.join(data_dir, 'data_batch_%d.bin' % i)for i in xrange(1, 6)]
        read_cifar = read_cifar10
        coarse_of_fine = None
    if cifar10or20or100 == 20:
        filenames = [os.path.join(data_dir, 'train.bin')]
        read_cifar = read_cifar100
        coarse_of_fine = 'coarse'
    if cifar10or20or100 == 100:
        filenames = [os.path.join(data_dir, 'train.bin')]
        read_cifar = read_cifar100
        coarse_of_fine = 'fine'
    # 检查数据文件是否存在,不存在报错
    for f in filenames:
        if not tf.gfile.Exists(f):
            raise ValueError('Failed to find file: ' + f)

    # 根据文件名列表创建一个文件名队列
    filename_queue = tf.train.string_input_producer(filenames)

    # 从文件名队列的文件中读取样本
    read_input = read_cifar(filename_queue,coarse_or_fine=coarse_of_fine)

    # 将无符号8位图像数据转换成 float32 位
    casted_image = tf.cast(read_input.uint8image, tf.float32)

    # 要生成的目标图像的大小, 在这里与原图像的尺寸保持一致
    height = IMAGE_SIZE
    width = IMAGE_SIZE

    # 为图像添加 Padding=4, 图像尺寸变为 [32+4,,32+4], 为后面的随机裁切流出位置
    padded_image = tf.image.resize_image_with_crop_or_pad(casted_image, width+4, height+4)

    # 下面的操作为原始图像添加了很多不同的 distortions, 扩增了原始训练数据集

    # 第一种,裁剪,在扩展的 [36, 36]大小的图像中随机裁剪出 [height,width], 即[32, 32] 的图像区域
    distorted_image = tf.random_crop(padded_image, [height, width, 3])

    # 第二种,水平翻转,将图像进行随机的水平翻转,(左边和右边的像素对调)
    distorted_image = tf.image.random_flip_left_right(distorted_image)

    # 下面这两个操作不满足交换律, 即 亮度调整+对比度调整 和 对比度调整+亮度调整,
    #  两个操作执行先后顺序产生的结果是不一样的, 可以采取随机的顺序来执行这两个操作
    # np.random.randn : 标准正太分布,均值:0;方差:1
    np_random_randn  = np.random.randn(1)
    if np_random_randn>0:
        # 第三种,亮度调整,原像素加上一个随机数,数的范围在 [-63,63]
        distorted_image = tf.image.random_brightness(distorted_image,
                                                   max_delta=63)
        # 第四种,对比度调整,原像素乘以一个随机数,数的范围在 [0.2, 1.8]
        distorted_image = tf.image.random_contrast(distorted_image,
                                                 lower=0.2, upper=1.8)
    else:
        # 第四种,对比度调整,原像素乘以一个随机数,数的范围在 [0.2, 1.8]
        distorted_image = tf.image.random_contrast(distorted_image,
                                                   lower=0.2, upper=1.8)
        # 第三种,亮度调整,原像素加上一个随机数,数的范围在 [-63,63]
        distorted_image = tf.image.random_brightness(distorted_image,
                                                     max_delta=63)


    # 数据集标准化操作: 减均值 + 方差归一化,
    float_image = tf.image.per_image_standardization(distorted_image)

    # 设置数据集中张量的形状
    float_image.set_shape([height, width, 3]) # 32*32*3
    read_input.label.set_shape([1])

    # Ensure that the random shuffling has good mixing properties.
    min_fraction_of_examples_in_queue = 0.4
    min_queue_examples = int(NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN *
                           min_fraction_of_examples_in_queue)
    print ('Filling queue with %d CIFAR images before starting to train. '
         'This will take a few minutes.' % min_queue_examples)

    # 通过构造样本队列产生一个批次的图像和标签
    return _generate_image_and_label_batch(float_image,
                                           read_input.label,
                                           min_queue_examples,
                                           batch_size,
                                           shuffle =True)


def inputs(cifar10or20or100,eval_data, data_dir, batch_size):
    """
    cifar10or20or100: 指定要读取的数据集是 cifar10 还是细分类 cifar100 或者粗分类 cifar100
    eval_data: Ture or False, 指示要读取的是训练集还是测试集
    data_dir: 指向 CIFAR-10 或者 CIFAR-100 数据集的目录
    batch_size: 单个批次的图像数量
    :return: images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size
             labels: Labels. 1D tensor of [batch_size] size
    """
    print('...正在调用...cifar_input...'+'cifar'+str(cifar10or20or100))

    # 判断是读取 cifar10 还是 cifar100 (cifar100又分20粗分类或者100细分类)
    if cifar10or20or100 ==10:
        read_cifar = read_cifar10
        coarse_of_fine = None
        if not eval_data:
            filenames = [os.path.join(data_dir, 'data_batch_%d.bin' % i)for i in xrange(1, 6)] # 列表生成
            num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
        else:
            filenames = [os.path.join(data_dir, 'test_batch.bin')]
            num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
    if cifar10or20or100 ==20 or cifar10or20or100 ==100:
        read_cifar = read_cifar100
        if not eval_data:
            filenames = [os.path.join(data_dir, 'train.bin')] # 列表生成
            num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
        else:
            filenames = [os.path.join(data_dir, 'test.bin')]
            num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
    if cifar10or20or100 == 100:
        coarse_of_fine = 'fine'
    if cifar10or20or100 == 20:
        coarse_of_fine = 'coarse'

    # 检查指定目录文件是否存在,不存在则报错
    for f in filenames:
        if not tf.gfile.Exists(f):
            raise ValueError('Failed to find file: ' + f)

    # 根据文件名列表创建一个文件名队列
    filename_queue = tf.train.string_input_producer(filenames)

    # 从文件名队列的文件中读取样本
    read_input = read_cifar(filename_queue, coarse_or_fine=coarse_of_fine)
    # 将无符号 8位图像数据转换成 float32 位
    casted_image = tf.cast(read_input.uint8image, tf.float32)

    # 要生成的目标图像的大小, 在这里与原图像的尺寸保持一致
    height = IMAGE_SIZE
    width = IMAGE_SIZE

    # 用于评估过程的图像数据预处理 ,此处原图像与处理后图像大小一样,都是32*32,则没有发生裁剪处理
    resized_image = tf.image.resize_image_with_crop_or_pad(casted_image,width, height)

    # 数据集标准化操作: 减去均值 + 方差归一化
    float_image = tf.image.per_image_standardization(resized_image)

    # 设置数据集中张量的形状
    float_image.set_shape([height, width, 3])
    read_input.label.set_shape([1])

    # Ensure that the random shuffling has good mixing properties.
    min_fraction_of_examples_in_queue = 0.4
    min_queue_examples = int(num_examples_per_epoch *
                           min_fraction_of_examples_in_queue)

    # 通过构造样本队列产生一个批次的图像和标签
    return _generate_image_and_label_batch(float_image,
                                           read_input.label,
                                           min_queue_examples,
                                           batch_size,shuffle=None)



convnets_test.py

import tensorflow as tf
import numpy as np
import csv
import cifar_input
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 超参数
learning_rate_init = 0.001 # 学习率
training_epochs = 10 # 训练轮数
batch_size = 100    # 一批次样本数量
display_step = 10   # 显示损失
conv1_kernel_num = 64   # 第一卷积层卷积核的数量
conv2_kernel_num = 64   # 第二卷积层卷积核的数量
fc1_units_num = 1024     # 第一全连接层,特征维度数量
fc2_units_num = 512      # 第二全连接层,特征维度数量

#数据集中输入图像的参数
dataset_dir_cifar10 = './CIFAR10_dataset/cifar-10-batches-bin'
dataset_dir_cifar100 = './CIFAR100_dataset/cifar-100-binary'

num_examples_per_epoch_for_train = cifar_input.NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
num_examples_per_epoch_for_eval = cifar_input.NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
image_size = cifar_input.IMAGE_SIZE # 图形大小 32*32*3
image_channel = cifar_input.IMAGE_DEPTH # 通道数

# 通过修改 cifar10or20or100, 就可以测试 cifar10, cifar20, cifar100
cifar10or20or100 = 10
# cifar10or20or100 = 20
# cifar10or20or100 = 100
if cifar10or20or100 == 10:
    n_classes = cifar_input.NUM_CLASSES_CIFAR10
    dataset_dir = dataset_dir_cifar10
if cifar10or20or100 == 20:
    n_classes = cifar_input.NUM_CLASSES_CIFAR20
    dataset_dir = dataset_dir_cifar100
if cifar10or20or100 == 100:
    n_classes = cifar_input.NUM_CLASSES_CIFAR100
    dataset_dir = dataset_dir_cifar100

# 获取训练 batch
def get_distorted_train_batch(data_dir, batch_size):
    if not data_dir:
        raise ValueError('Please supply a data_dir')
    images, labels = cifar_input.distorted_inputs(cifar10or20or100=n_classes,
                                                  data_dir=data_dir,
                                                  batch_size=batch_size)
    return images, labels

# 获取评估 batch
def get_undistorted_eval_batch(data_dir,eval_data,batch_size):
    if not data_dir:
        raise ValueError('Please supply a data_dir')
    images,labels = cifar_input.inputs(cifar10or20or100=n_classes,
                                        eval_data=eval_data,
                                        data_dir=data_dir,
                                        batch_size=batch_size)
    return images,labels

# W,根据指定的维数返回初始化好的指定名称的权重,
def WeightsVariable(shape,name_str,stddev=0.1):
    initial = tf.truncated_normal(shape=shape,stddev=stddev,dtype=tf.float32)#截断正太分布
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

# b,根据指定的维数返回初始化好的指定名称的偏置,
def BiasesVariable(shape,name_str,init_value=0.0):
    initial = tf.constant(init_value,shape=shape)# 常量节点
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

# 2维卷积层 activation (conv2d+bias) 的封装
def Conv2d(x,W,b,stride=1,padding='SAME',activation=tf.nn.relu,act_name='relu'):
    with tf.name_scope('conv2d_bias'):
        y = tf.nn.conv2d(x,W,strides=[1,stride,stride,1],padding=padding)
        y = tf.nn.bias_add(y,b)
    with tf.name_scope(act_name):
        y = activation(y)
    return y

# 2维池化层pool的封装
def Pool2d(x,pool=tf.nn.max_pool,k=2,stride=2,padding='SAME'):
    return pool(x,ksize=[1,k,k,1],strides=[1,stride,stride,1],padding=padding)

# 全连接层 activation (wx+b) 的封装
def FullyConnected(x,W,b,activate=tf.nn.relu,act_name='relu'):
    with tf.name_scope('Wx_b'):
        y = tf.matmul(x,W)
        y = tf.add(y,b)
    with tf.name_scope(act_name):
        y = activate(y)
    return y

# 为每一层的激活输出添加汇总节点
def AddActivationSummary(x):
    tf.summary.histogram('/activations',x)
    tf.summary.scalar('/sparsity',tf.nn.zero_fraction(x))

# 为所有损失节点添加(滑动平均)标量汇总操作
def AddLossesSummary(losses):
    # 计算所有(individual loss)和 (total loss) 的滑动平均
    loss_averages = tf.train.ExponentialMovingAverage(0.9,name='avg')
    loss_averages_op = loss_averages.apply(losses)
    # 为所有 (individual loss)和 (total loss)  绑定标量汇总节点
    # 为所有平滑处理过的(individual loss)和 (total loss) 也绑定标量汇总节点
    for loss in losses:
        # 没有平滑过的 loss 名字后面加上(raw),
        # 平滑过的 loss 使用其原来的名字
        tf.summary.scalar(loss.op.name + '(raw)', loss)
        tf.summary.scalar(loss.op.name + '(avg)',loss_averages.average(loss))
    return loss_averages_op

# 前向推断过程,Inference
def Inference(images_holder):
    "此处设置前向推断层,包括两个卷积层,两个池化层,一个多维转一维层,三个全连接层,"
    # 第一个卷积层,activate,(conv2d+bias)
    with tf.name_scope('Conv2d_1'):
        weights = WeightsVariable(shape=[5,5,image_channel,conv1_kernel_num],
                                  name_str='weights',
                                  stddev=5e-2)
        biases = BiasesVariable(shape=[conv1_kernel_num],
                                  name_str='biases',
                                init_value=0.0)
        conv1_out = Conv2d(images_holder,weights,biases,stride=1,padding='SAME')
        AddActivationSummary(conv1_out)
    # 第一个池化层
    with tf.name_scope('Pool2d_1'):
        pool1_out = Pool2d(conv1_out,pool=tf.nn.max_pool,k=3,stride=2,padding='SAME')
    # 第二个卷积层,activate,(conv2d+bias)
    with tf.name_scope('Conv2d_2'):
        weights = WeightsVariable(shape=[5, 5, conv1_kernel_num, conv2_kernel_num],
                                  name_str='weights',
                                  stddev=5e-2)
        biases = BiasesVariable(shape=[conv2_kernel_num],
                                name_str='biases',
                                init_value=0.0)
        conv2_out = Conv2d(pool1_out, weights, biases, stride=1, padding='SAME')
        AddActivationSummary(conv2_out)
    # 第二个池化层
    with tf.name_scope('Pool2d_2'):
        pool2_out = Pool2d(conv2_out,pool=tf.nn.max_pool,k=3,stride=2,padding='SAME')
    # 将二维特征图转换为一维特征向量
    with tf.name_scope('FeatReshape'):
        features = tf.reshape(pool2_out,[batch_size,-1]) # [batch_size,6*6*64]
        feats_dim = features.get_shape()[1].value   # 6*6*64
    # 第一个全连接层,nonlinear
    with tf.name_scope('FC1_nonlinear'):
        weights = WeightsVariable(shape=[feats_dim, fc1_units_num],
                                  name_str='weights',
                                  stddev=4e-2)
        biases = BiasesVariable(shape=[fc1_units_num],
                                name_str='biases',
                                init_value=0.1)
        fc1_out = FullyConnected(features, weights, biases,
                                  activate=tf.nn.relu,
                                  act_name='relu')
        AddActivationSummary(fc1_out)
    # 第二个全连接层,nonlinear
    with tf.name_scope('FC2_nonlinear'):
        weights = WeightsVariable(shape=[fc1_units_num, fc2_units_num],
                                  name_str='weights',
                                  stddev=4e-2)
        biases = BiasesVariable(shape=[fc2_units_num],
                                name_str='biases',
                                init_value=0.1)
        fc2_out = FullyConnected(fc1_out, weights, biases,
                                 activate=tf.nn.relu,
                                 act_name='relu')
        AddActivationSummary(fc2_out)
    # 第三个全连接层,linear
    with tf.name_scope('FC3_linear'):
        fc3_units_num = n_classes
        weights = WeightsVariable(shape=[fc2_units_num, fc3_units_num],
                                  name_str='weights',
                                  stddev=1.0/fc2_units_num)
        biases = BiasesVariable(shape=[fc3_units_num],
                                name_str='biases',
                                init_value=0.0)
        logits = FullyConnected(fc2_out, weights, biases,
                                 activate=tf.identity,
                                 act_name='linear')
        AddActivationSummary(logits)
    return logits

def TrainModel():
    # 调用上面写的函数构造计算图
    with tf.Graph().as_default():
        # 计算图输入层,Inputs
        with tf.name_scope('Inputs'):
            images_holder = tf.placeholder(tf.float32,
                                           [batch_size,image_size,image_size,image_channel],
                                           name='images')
            labels_holder = tf.placeholder(tf.int32,
                                           [batch_size],
                                           name='labels')
        # 计算图前向推断过程 Inference
        with tf.name_scope('Inference'):
            logits = Inference(images_holder)
        # 计算图,损失层 loss
        with tf.name_scope('Loss'):
            cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels_holder,
                                                                           logits=logits)
            cross_entropy_loss = tf.reduce_mean(cross_entropy, name='xentropy_loss')
            total_loss = cross_entropy_loss
            average_losses = AddLossesSummary([total_loss])
        # 计算图 ,优化训练层,train
        with tf.name_scope('Train'):
            learning_rate = tf.placeholder(tf.float32)
            global_step = tf.Variable(0, name='global_step',
                                      trainable=False,
                                      dtype=tf.int64)
            optimizer = tf.train.RMSPropOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)
            # optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.FtrlOptimizer(learning_rate=learning_rate)
            train_op = optimizer.minimize(total_loss,global_step=global_step)
        # 评估层,Evalute
        with tf.name_scope('Evaluate'):
            top_K_op = tf.nn.in_top_k(predictions=logits,
                                      targets=labels_holder,
                                      k=1)

        # 获取数据
        # 定义获取训练样本批次的计算节点(有数据增强distorted)
        with tf.name_scope('GetTrainBatch'):
            images_train,labels_train = get_distorted_train_batch(data_dir=dataset_dir,
                                                                  batch_size=batch_size)
            # 对一个批次的训练数据集进行汇总,最多汇总9个图像
            tf.summary.image('images',images_train, max_outputs=9)
        # 定义获取测试样本批次的节点
        with tf.name_scope('GetTestBatch'):
            images_test,labels_test = get_undistorted_eval_batch(eval_data=True,
                                                                 data_dir=dataset_dir,
                                                                 batch_size=batch_size)
        tf.summary.image('images', images_test, max_outputs=9)

        # 收集所有汇总节点
        merged_summaries = tf.summary.merge_all()

        # 添加初始化节点
        init_op = tf.global_variables_initializer()

        print('把计算图写入事件文件,在TensorBoard里面查看')
        summary_writer = tf.summary.FileWriter(logdir='logs')
        summary_writer.add_graph(graph=tf.get_default_graph())
        summary_writer.flush()

        # 将评估结果保存到csv文件中
        results_list = list()
        # 写入参数配置
        results_list.append(['learning_rate',learning_rate_init,
                             'training_epoches',training_epochs,
                             'batch_size',batch_size,
                             'display_step',display_step,
                             'conv1_kernel_num',conv1_kernel_num,
                             'conv2_kernel_num',conv2_kernel_num,
                             'fc1_units_num',fc1_units_num,
                             'fc2_units_num',fc2_units_num])
        # csv中添加表头,
        results_list.append(['train_step','train_loss','train_step','train_accuracy'])

        # 开始训练 ,Session
        with tf.Session() as sess:
            # sess = tf.Session()
            sess.run(init_op)
            # 启动数据读取对列
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess=sess, coord=coord)
            # tf.train.start_queue_runners()

            print('===>>>===开始在训练集上训练模型===<<<===')
            num_batches_per_epoch = int(num_examples_per_epoch_for_train/batch_size)
            print('Total epoch Count:',training_epochs)
            print('Per batch Size:',batch_size)
            print('Train sample Count Per Epoch:',num_examples_per_epoch_for_train)
            print('Total batch Count Per Epoch:',num_batches_per_epoch)


            # 记录模型被训练的步数
            training_step = 0
            # 训练指定轮数, 每一轮的训练样本总数为:num_examples_per_epoch_for_train
            for epoch in range(training_epochs):
                # 每一轮都要把所有的batch 跑一边
                for batch_idx in range(num_batches_per_epoch):
                    # 运行获取训练数据的计算图,取出一个批次数量
                    images_batch,labels_batch = sess.run([images_train,labels_train])
                    # 运行优化器训练节点
                    _,loss_value = sess.run([train_op,total_loss],
                                            feed_dict={images_holder:images_batch,
                                                       labels_holder:labels_batch,
                                                       learning_rate:learning_rate_init})
                    # 每调用一次训练节点, training_step就加1,最终==training_epochs*total_batch
                    training_step = sess.run(global_step)
                    # 每训练display_step 次, 计算当前模型的损失和分类准确率
                    if training_step % display_step==0:
                        # 运行 accuracy 节点, 计算当前批次的训练样本的准确率
                        predictions = sess.run([top_K_op],
                                               feed_dict={images_holder:images_batch,
                                                          labels_holder :labels_batch})
                        # 当前每个批次上的预测正确的样本量
                        batch_accuracy = np.sum(predictions)*1.0/batch_size
                        results_list.append([training_step,loss_value,training_step,batch_accuracy])
                        print('Training Epoch: '+str(epoch)+
                               ', Training Step:'+str(training_step)+
                               ', Training Loss = {:.6f}'.format(loss_value)+
                               ', Training Accuracy = {:.5f}'.format(batch_accuracy))
                        # 运行汇总节点
                        summary_str = sess.run(merged_summaries,
                                               feed_dict={images_holder:images_batch,
                                                          labels_holder:labels_batch})
                        summary_writer.add_summary(summary=summary_str, global_step=training_step)
                        summary_writer.flush()
            summary_writer.close()
            print('训练完毕!')

            print('===>>>===开始在测试集上测试模型===<<<===')
            total_batches = int(num_examples_per_epoch_for_eval / batch_size)
            total_examples = total_batches*batch_size
            print('Per batch Size:', batch_size)
            print('Test sample Count Per Epoch:', total_examples)
            print('Total batch Count Per Epoch:', total_batches)
            correct_predicted = 0
            for test_step in range(total_batches):
                # 运行获取测试数据的计算图, 取出一个批次测试数据,
                images_batch,labels_batch = sess.run([images_test,labels_test])
                # 运行 accuracy 节点,计算当前批次的测试样本的准确率
                predictions = sess.run([top_K_op],
                                       feed_dict={images_holder: images_batch,
                                                  labels_holder: labels_batch})
                # 累积每个批次上的预测正确的样本量
                correct_predicted += np.sum(predictions)
            accuracy_score = correct_predicted*1.0/total_examples
            print('------------>Accuracy on Test Examples:',accuracy_score)
            results_list.append(['Accuracy on Test Examples:',accuracy_score])

        # 将评估结果保存到文件中
        results_file = open('evaluate_results.csv','w', newline='')
        csv_writer = csv.writer(results_file,dialect='excel')
        for row in results_list:
            csv_writer.writerow(row)

def main(argv=None):
    # 下载数据 cifar10 ,cifar100,如果存在则不执行下载,
    CIFAR10_DATA_URL = cifar_input.CIFAR10_DATA_URL
    CIFAR100_DATA_URL = cifar_input.CIFAR100_DATA_URL
    cifar_input.maybe_download_and_extract('./CIFAR10_dataset', CIFAR10_DATA_URL)
    cifar_input.maybe_download_and_extract('./CIFAR100_dataset', CIFAR100_DATA_URL)

    # 日志文件,
    train_dir = 'logs/'
    if tf.gfile.Exists(train_dir):
        tf.gfile.DeleteRecursively(train_dir)
    tf.gfile.MakeDirs(train_dir)
    TrainModel()

if __name__ == '__main__':
    tf.app.run()

(0) 回复

普陀 回复 普陀 1年前

第五章,cifar10_cifar100数据读取以及用CNN测试

(0) 回复

剪刀布石头 回复 普陀 1年前

视频不可以看吗?一直缓存

(0) 回复

普陀 1年前 26声望

import tensorflow as tf
import numpy as np
import csv
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 设置学习率超参数
training_epochs = 5
num_examples_per_epoch_for_train = 10000
batch_size = 100
learning_rate_init = 0.1 # 初始学习率
learning_rate_final = 0.001 # 结束学习率
learning_rate_decay_rate = 0.5
num_batches_per_epoch = int(num_examples_per_epoch_for_train/batch_size)
num_epochs_per_decay  = 1  # Epochs after which learning rate decays
learning_rate_decay_steps = int(num_batches_per_epoch * num_epochs_per_decay)

with tf.Graph().as_default():

    # 优化器调用次数计数器, 全局训练步数
    global_step = tf.Variable(0, name='global_step', trainable=False, dtype=tf.int64)

    # 使用 exponential_decay(...)产生指数衰减的学习率
    # learning_rate = tf.train.exponential_decay(learning_rate_init,
    #                                            global_step,
    #                                            learning_rate_decay_steps,
    #                                            learning_rate_decay_rate,
    #                                            staircase=False)
    # 使用 polynomial_decay(...)产生多项式衰减的学习率
    # learning_rate = tf.train.polynomial_decay(learning_rate_init,
    #                                            global_step,
    #                                            learning_rate_decay_steps,
    #                                            learning_rate_decay_rate,
    #                                            power=0.5,
    #                                           cycle=False)
    # 使用 natural_exp_decay(...)产生自然指数衰减的学习率
    # learning_rate = tf.train.natural_exp_decay(learning_rate_init,
    #                                            global_step,
    #                                            learning_rate_decay_steps,
    #                                            learning_rate_decay_rate,
    #                                            staircase=False)
    # 使用 inverse_time_decay(...)产生反时限衰减的学习率
    learning_rate = tf.train.inverse_time_decay(learning_rate_init,
                                               global_step,
                                               learning_rate_decay_steps,
                                               learning_rate_decay_rate,
                                               staircase=False)

    # 定义损失函数
    weights = tf.Variable(tf.random_normal([9000,9000], mean=0.0, stddev=1e9, dtype=tf.float32))
    myloss = tf.nn.l2_loss(weights,name='L2Loss')

    # 传入 learning_rate 创建优化器
    optimizer = tf.train.GradientDescentOptimizer(learning_rate)
    # 将 global_step 传入 minimize() .每次调用 minimize 都会使得 globa_step 自增
    training_op = optimizer.minimize(myloss, global_step=global_step)

    # 添加所有变量的初始化节点
    init_op = tf.global_variables_initializer()

    # 将评估结果保存到文件
    results_list = list()
    results_list.append(['train_step', 'learning_rate', 'train_step', 'train_loss'])

    # 启动会话, 训练模型
    with tf.Session() as sess:
        sess.run(init_op)
        # 训练指定轮数, 每一轮的训练样本总数为:num_examples_per_epoch_for_train
        for epoch in range(training_epochs):
            print("**********************************************")
            # 每一轮都要把所有的 batch 跑一遍
            for batch_idx in range(num_batches_per_epoch):
                # 获取 learning_rate 的值
                current_learning_rate  = sess.run(learning_rate)
                # 执行训练节点, 获取损失节点和 globals_step 的值
                _, loss_value, training_step = sess.run([training_op, myloss, global_step])

                print("Training Epoch:"+str(epoch)+
                      ", Training Step:"+str(training_step)+
                      ", Learning Rate= "+"{:.6f}".format(current_learning_rate)+
                      ", Training Loss= "+"{:.6f}".format(loss_value))
                # 记录结果
                results_list.append([training_step, current_learning_rate, training_step,loss_value])

    # 将评估结果保存文件
    print('训练结束, 将结果保存到文件')
    results_file = open('./learning_rate_results/lr_evaluate_results.csv', 'w', newline='')
    csv_writer = csv.writer(results_file, dialect='excel')
    for row in results_list:
        csv_writer.writerow(row)

(0) 回复

普陀 回复 普陀 1年前

第四章,学习率衰减代码,

(0) 回复

Coastline2018 1年前 22声望

老师,你好!请问循环神经网络和LSTM什么时候可以讲一下呢?

(0) 回复

erhafang 1年前 15声望

请问我的CSV写入文件为什么数据都不分开的,直接在一个格子里面了

(0) 回复

一路向北 1年前 41声望

问个问题,如果激活函数不是连续平滑的,怎么进行反向传播?
比方说RELU,在零点我们究竟应该取它的导数是多少?0 or 1?


(0) 回复

dafei 1年前 12声望

 你好,老师,请问课程什么时候讲到lstm网络,或者提前给点指导,非常感谢

(0) 回复

itmessager 1年前 39声望

课件都停止更新了吗?

(1) 回复

菜鸟后飞 回复 itmessager 1年前

最近很忙 啊 抱歉啦

(0) 回复

itmessager 1年前 39声望

什么时候更细第四章的代码啊?

(1) 回复

菜鸟后飞 回复 itmessager 1年前

忙完更新

(0) 回复

爱读知行合一 1年前 99声望

希望老师能讲一讲,怎样用tensorflow制作自己的数据集??

(1) 回复

Coastline2018 回复 爱读知行合一 1年前

我也是,现在需要做点云分割数据集的制作,希望可以讲一下这方面的

(0) 回复

wudixx 1年前 153声望

期待老师第四章以后的代码更新

(0) 回复

wudixx 1年前 153声望

这个要pip 安装sklearn包才能正常运行

(0) 回复

adam 1年前 19声望

希望Antares老师可以及时将课程中的配套代码贴出,或提供下载链接,方便同学们实践操作。


(0) 回复

verigle 1年前 13声望

请问在哪里可以找到源码?

(0) 回复

菜鸟后飞 回复 verigle 1年前

http://studyai.com/antares?category=TensorFlow中级教程

(0) 回复

verigle 回复 菜鸟后飞 1年前

第四章的代码更新了吗?

(0) 回复

FMsunyh 2年前 8声望

老师,这个什么时候更新?

(1) 回复

yww 2年前 21声望

请问一下全部按照老师4.2上下视频中敲出来的代码出现以下错误是什么原因呢

TypeError: Value passed to parameter 'shape' has DataType float32 not in list of allowed values: int32, int64

(0) 回复

onemore 回复 yww 2年前

很明显类型错误。。

(0) 回复

zcc 2年前 0声望

是还没有更新完吗,没有找到中级课程中InceptionNet的课程

(0) 回复

katherine_shaw 2年前 0声望

第6章,cifar数据集的alexnet实现,想知道为什么程序一直卡在这儿不动了,也不知bug在哪里


(0) 回复

菜鸟后飞 回复 katherine_shaw 2年前

重新调整模型

(0) 回复

verigle 回复 katherine_shaw 1年前

linux 下跑下代码试试

(0) 回复

zcc 2年前 0声望

第六章第2节:用于ImageNet的AlexNet网络的假数据训练

老师最后提到的扣扣数据集是什么,有数据集下载链接吗?

(0) 回复

菜鸟后飞 回复 zcc 2年前

叫 MSCOCO 微软出的分类检测分割数据集 百度一下

(0) 回复

zcc 回复 菜鸟后飞 2年前

了解,谢谢

(0) 回复

zcc 2年前 0声望

老师,如何保存训练好的模型?是否有课程提到这个?

(0) 回复

菜鸟后飞 回复 zcc 2年前

训练过程中会生成checkpoint文件,就是模型参数。 可以按需求保存。

(0) 回复

萌萌小妖 2年前 0声望

你好,我想请问一下,因为我已经下载好了数据集,所以我想直接从本地加载,我下载在E:\python\aaa\cifar10\cifar-10-batches-bin中,然后我就把maybe_download_and_extract(data_dir)这个函数删除了,其他的都没有变,但是我把dataset_dir的路径,但是似乎没有什么用,数据集无法加载,而且我从网上找了很多资料,但是没有用,因为我的马上要做的项目中需要自己做数据集,所以想各方面了解一下,我上传我的错误给您,如果耽误您一点时间。QQ截图20170825155520


(0) 回复

萌萌小妖 回复 萌萌小妖 2年前

老师,我已经解决了,主要是我的文件夹名字aaa存在问题,好像和系统文件冲突了\a貌似是一个命令

(1) 回复

zcc 2年前 0声望

能不能贴出代码哇,老师

(0) 回复

哈哈哈哈哈哈哈 2年前 4声望

fullsizeoutput_21a

老师您好,我在学习降噪自动编码器那节的时候,按照您的代码运行之后出现这种错误,我该怎么办呢


(0) 回复

JJZHK 回复 哈哈哈哈哈哈哈 2年前

仔细检查你的代码,有些地方写错了。

(0) 回复

哈哈哈哈哈哈哈 回复 JJZHK 2年前

我查了一下这个typeerror是说没有标注类型的不能和整数类型相除,可是我是按照老师在视频上的操作来敲的诶 我检查了其他地方都是一样的 我想问的是难道是TensorFlow版本的问题么

(0) 回复

jianxiong0117 2年前 4声望

Antares老师讲得特别好!希望老师能够早点做个用PAI训练大型网络的教程

(0) 回复

天真 2年前 0声望

有没有用GPU跑cifar10实验的?为什么我按照上面的代码跑,所有的负载几乎都子啊CPU上,GPU几乎没有负载。

跑过其他的没发生过这样的问题。




(0) 回复

天才卡门 2年前 0声望

这些视频如何下载啊?

(0) 回复

bliang1982 回复 天才卡门 2年前

无法下载 因为标记为原创 网上看吧 支持老师 多点点击量

(0) 回复

jianxiong0117 2年前 4声望

我也贴上我第四章的代码:

excise4.py

#coding:utf-8
import tensorflow as tf
import numpy as np
import os
import sys
import tarfile
import csv
from six.moves import urllib
import cifar10_input
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#设置算法超参数
learning_rate_init = 0.001
training_epochs = 6
batch_size = 100
display_step = 20
conv1_kernel_num = 32
conv2_kernel_num = 32
fc1_units_num = 192
fc2_units_num = 96

#数据集中输入图像的参数
dataset_dir = '../CIFAR10_dataset'
num_examples_per_epoch_for_train = cifar10_input.NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
num_examples_per_epoch_for_eval = cifar10_input.NUM_EXAMPLES_PER_EPOCH_FOR_EVAL
image_size = cifar10_input.IMAGE_SIZE
image_channel = 3
n_classes = cifar10_input.NUM_CLASSES

#从网址下载数据集存放到data_dir指定的目录下****************
def maybe_download_and_extract(data_dir):
    """下载并解压数据集from Alex's website."""
    dest_directory = data_dir
    DATA_URL = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'
    if not os.path.exists(dest_directory):
        os.makedirs(dest_directory)
    filename = DATA_URL.split('/')[-1]
    filepath = os.path.join(dest_directory,filename)
    if not os.path.exists(filepath):
        def _progress(count,block_size,total_size):
            sys.stdout.write('\r>>Downloading %s %.1f%%'%(filename,
                                                          float(count*batch_size)/float(total_size)*100.0))
            sys.stdout.flush()
        filepath,_ = urllib.request.urlretrieve(DATA_URL,filepath,_progress)
        print()
        statinfo = os.stat(filepath)
        print 'Successfully downloaded',filename,statinfo.st_size,'bytes.'

    tarfile.open(filepath,'r:gz').extractall(dest_directory)

def get_distorted_train_batch(data_dir,batch_size):
    if not data_dir:
        raise ValueError('Please supply a data_dir')
    data_dir = os.path.join(data_dir,'cifar-10-batches-bin')
    images,labels = cifar10_input.distorted_inputs(data_dir=data_dir,batch_size=batch_size)
    return images,labels

def get_undistorted_eval_batch(data_dir,eval_data,batch_size):
    if not data_dir:
        raise ValueError('Please supply a data_dir')
    data_dir = os.path.join(data_dir,'cifar-10-batches-bin')
    images,labels = cifar10_input.inputs(eval_data=eval_data,
                                         data_dir=data_dir,
                                         batch_size=batch_size)
    return images,labels

#根据指定的维数返回初始化好的指定名称的权重
def WeightsVariable(shape,name_str,stddev=0.1):
    initial = tf.truncated_normal(shape=shape,stddev=stddev,dtype=tf.float32)
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

#根据指定的维数返回初始化好的指定名称的偏置
def BiasesVariable(shape,name_str,init_value=0.0):
    initial = tf.constant(init_value,shape=shape)
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

#2维卷积层activation(conv2d+bias)的封装
def Conv2d(x,W,b,stride=1,padding='SAME',activation=tf.nn.relu,act_name='relu'):
    with tf.name_scope('conv2d_bias'):
        y = tf.nn.conv2d(x,W,strides=[1,stride,stride,1],padding=padding)
        y = tf.nn.bias_add(y,b)
    with tf.name_scope(act_name):
        y = activation(y)
    return y

#2维池化层pool的封装
def Pool2d(x,pool=tf.nn.max_pool,k=2,stride=2,padding='SAME'):
    return pool(x,ksize=[1,k,k,1],strides=[1,stride,stride,1],padding=padding)

#全连接层activation(wx+b)的封装
def FullyConnected(x,W,b,activate=tf.nn.relu,act_name='relu'):
    with tf.name_scope('Wx_b'):
        y = tf.matmul(x,W)
        y = tf.add(y,b)
    with tf.name_scope(act_name):
        y = activate(y)
    return y

#为每一层的激活输出添加汇总节点
def AddActivationSummary(x):
    tf.summary.histogram('/activations',x)
    tf.summary.scalar('/sparsity',tf.nn.zero_fraction(x))

#为所有损失节点添加(滑动平均)标量汇总操作
def AddLossesSummary(losses):
    #计算所有(individual losses)和(total loss)的滑动平均
    loss_averages = tf.train.ExponentialMovingAverage(0.9,name='avg')
    loss_averages_op = loss_averages.apply(losses)
    #为所有(individual losses)和(total loss)绑定标量汇总节点
    #为所有平滑处理过的(individual losses)和(total loss)也绑定标量汇总节点
    for loss in losses:
        #没有平滑过的loss名字后面加上(raw),平滑后的loss使用其原来的名称
        tf.summary.scalar(loss.op.name + '(raw)',loss)
        tf.summary.scalar(loss.op.name + '(avg)',loss_averages.average(loss))
    return loss_averages_op

#前向推断过程
def Inference(images_holder):
    #第一个卷积层activate(conv2d+bias)
    with tf.name_scope('Conv2d_1'):
        weights = WeightsVariable(shape=[5,5,image_channel,conv1_kernel_num],
                                  name_str='weights',stddev=5e-2)
        biases = BiasesVariable(shape=[conv1_kernel_num],name_str='biases',init_value=0.0)
        conv1_out = Conv2d(images_holder,weights,biases,stride=1,padding='SAME')
        AddActivationSummary(conv1_out)
    #第一个池化层
    with tf.name_scope('Pool2d_1'):
        pool1_out = Pool2d(conv1_out,pool=tf.nn.max_pool,k=3,stride=2,padding='SAME')
    #第二个卷积层
    with tf.name_scope('Conv2d_2'):
        weights = WeightsVariable(shape=[5,5,conv1_kernel_num,conv2_kernel_num],
                                  name_str='weights', stddev=5e-2)
        biases = BiasesVariable(shape=[conv2_kernel_num], name_str='biases', init_value=0.0)
        conv2_out = Conv2d(pool1_out, weights, biases, stride=1, padding='SAME')
        AddActivationSummary(conv2_out)
    #第二个池化层
    with tf.name_scope('Pool2d_2'):
        pool2_out = Pool2d(conv2_out, pool=tf.nn.max_pool, k=3, stride=2, padding='SAME')
    #将二维特征图变换为一维特征向量
    with tf.name_scope('FeatsReshape'):
        features = tf.reshape(pool2_out,[batch_size,-1])  #[batch_size,6*6*64]
        feats_dim = features.get_shape()[1].value   #6*6*64
    #第一个全连接层
    with tf.name_scope('FC1_nonlinear'):
        weights = WeightsVariable(shape=[feats_dim,fc1_units_num],
                                  name_str='weights',stddev=4e-2)
        biases = BiasesVariable(shape=[fc1_units_num],name_str='biases',init_value=0.1)
        fc1_out = FullyConnected(features,weights,biases,activate=tf.nn.relu,act_name='relu')
        AddActivationSummary(fc1_out)
    #第二个全连接层
    with tf.name_scope('FC2_nonlinear'):
        weights = WeightsVariable(shape=[fc1_units_num,fc2_units_num],
                                  name_str='weights',stddev=4e-2)
        biases = BiasesVariable(shape=[fc2_units_num],name_str='biases', init_value=0.1)
        fc2_out = FullyConnected(fc1_out, weights, biases, activate=tf.nn.relu, act_name='relu')
        AddActivationSummary(fc2_out)
    #第三个全连接层
    with tf.name_scope('FC3_linear'):
        fc3_units_num = n_classes
        weights = WeightsVariable(shape=[fc2_units_num, fc3_units_num],
                                  name_str='weights', stddev=1.0/fc2_units_num)
        biases = BiasesVariable(shape=[fc3_units_num], name_str='biases', init_value=0.0)
        logits = FullyConnected(fc2_out, weights, biases, activate=tf.identity, act_name='linear')
        AddActivationSummary(logits)
    return logits

def TrainModel():
    #调用上面写的函数构造计算图
    with tf.Graph().as_default():
        #计算图输入
        with tf.name_scope('Inputs'):
            images_holder = tf.placeholder(tf.float32,[batch_size,image_size,image_size,image_channel],name='images')
            labels_holder = tf.placeholder(tf.int32,[batch_size],name='labels')
        #计算图前向推断过程
        with tf.name_scope('Inference'):
            logits = Inference(images_holder)
        #定义损失层(loss layer)
        with tf.name_scope('Loss'):
            cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
                labels=labels_holder,logits=logits)
            cross_entropy_loss = tf.reduce_mean(cross_entropy,name='xentropy_loss')
            total_loss = cross_entropy_loss
            average_losses = AddLossesSummary([total_loss])
        #定义优化训练层(train layer)
        with tf.name_scope('Train'):
            learning_rate = tf.placeholder(tf.float32)
            global_step = tf.Variable(0,name='global_step',trainable=False,dtype=tf.int64)
            optimizer = tf.train.RMSPropOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.MomentumOptimizer(learning_rate=learning_rate,momentum=0.9)
            # optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
            # optimizer = tf.train.FtrlOptimizer(learning_rate=learning_rate)
            train_op = optimizer.minimize(total_loss,global_step=global_step)
        #定义模型评估层(evaluate layer)
        with tf.name_scope('Evaluate'):
            top_K_op = tf.nn.in_top_k(predictions=logits,targets=labels_holder,k=1)
        #定义获取训练样本批次的计算节点(有数据增强distorted)
        with tf.name_scope('GetTrainBatch'):
            images_train,labels_train = get_distorted_train_batch(data_dir=dataset_dir,
                                                                  batch_size=batch_size)
        #定义获取测试样本批次的节点
        with tf.name_scope('GetTestBatch'):
            images_test,labels_test = get_undistorted_eval_batch(eval_data=True,
                                                                 data_dir=dataset_dir,
                                                                 batch_size=batch_size)

        #收集所有汇总节点
        merged_summaries = tf.summary.merge_all()

        #添加所有变量的初始化节点
        init_op = tf.global_variables_initializer()

        print '把计算图写入事件文件,在TensorBoard里面查看'
        summary_writer = tf.summary.FileWriter(logdir='logs/excise411')
        summary_writer.add_graph(graph=tf.get_default_graph())
        summary_writer.flush()

        #将评估结果保存到csv文件
        results_list = list()
        #写入参数配置
        results_list.append(['learning_rate',learning_rate_init,
                             'training_epochs',training_epochs,
                             'batch_size',batch_size,
                             'display_step',display_step,
                             'conv1_kernel_num',conv1_kernel_num,
                             'conv2_kernel_num',conv2_kernel_num,
                             'fc1_units_num',fc1_units_num,
                             'fc2_units_num',fc2_units_num])
        results_list.append(['train_step','train_loss','train_step','train_accuracy'])

        with tf.Session() as sess:
            sess.run(init_op)
            print '======>>>>>>>>>>==开始在训练集上训练模型==<<<<<<<<<<<======'
            total_batches = int(num_examples_per_epoch_for_train/batch_size)
            print "Total epoch Count:",training_epochs
            print "Per batch Size:",batch_size
            print "Train sample Count Per Epoch:",num_examples_per_epoch_for_train
            print "Total batch Count Per Epoch:",total_batches
            #启动数据读取队列
            coord = tf.train.Coordinator()
            threads = tf.train.start_queue_runners(sess=sess,coord=coord)
            #记录模型被训练的步数
            training_step = 0
            #训练指定轮数,每一轮的训练样本总数为:num_examples_per_epoch_for_train
            for epoch in range(training_epochs):
                #每一轮都要把所有的batch跑一边
                for batch_idx in range(total_batches):
                    #运行获取训练数据的计算图,取出一个批次数据
                    images_batch,labels_batch = sess.run([images_train,labels_train])
                    #运行优化器训练节点
                    _,loss_value = sess.run([train_op,total_loss],
                                            feed_dict={images_holder:images_batch,
                                                        labels_holder:labels_batch,
                                                       learning_rate:learning_rate_init})
                    #每调用一次训练节点,training_step就加1,最终==training_epochs*total_batch
                    training_step = sess.run(global_step)
                    #每训练display_step次,计算当前模型的损失和分类准确率
                    if training_step % display_step == 0:
                        #运行accuracy节点,计算当前批次的训练样本的准确率
                        predictions = sess.run([top_K_op],
                                               feed_dict={images_holder:images_batch,
                                                          labels_holder:labels_batch})
                        #当前每个批次上的预测正确的样本量
                        batch_accuracy = np.sum(predictions)*1.0 / batch_size
                        results_list.append([training_step,loss_value,training_step,batch_accuracy])
                        print "Training Step: ",str(training_step),",Training Loss= {:.6f}".format(loss_value),",Training Accuracy= {:.5f}".format(batch_accuracy)
                        #运行汇总节点
                        summary_str = sess.run(merged_summaries,feed_dict=
                                                    {images_holder:images_batch,
                                                     labels_holder:labels_batch})
                        summary_writer.add_summary(summary=summary_str,global_step=training_step)
                        summary_writer.flush()

            summary_writer.close()
            print "训练完毕!"

            print '======>>>>>>>>>>==开始在测试集上训练模型==<<<<<<<<<<<======'
            total_batches = int(num_examples_per_epoch_for_eval/batch_size)
            total_examples = total_batches*batch_size
            print "Per batch Size:", batch_size
            print "Test sample Count Per Epoch:", total_examples
            print "Total batch Count Per Epoch:", total_batches
            correct_predicted = 0
            for test_step in range(total_batches):
                #运行获取测试数据的计算图,取出一个批次测试数据
                images_batch,labels_batch = sess.run([images_test,labels_test])
                #运行accuracy节点,计算当前批次的测试样本的准确率
                predictions = sess.run([top_K_op],
                                       feed_dict={images_holder:images_batch,
                                                  labels_holder:labels_batch})
                #累计每个批次上的预测正确的样本量
                correct_predicted += np.sum(predictions)

            accuracy_score = correct_predicted*1.0/total_examples
            print "-------------->Accuracy on Test Examples:",accuracy_score
            results_list.append(['Accuracy on Test Examples: ',accuracy_score])

        #将评估结果保存到文件
        results_file = open('evaluate_results.csv','w')
        csv_writer = csv.writer(results_file,dialect='excel')
        for row in results_list:
            csv_writer.writerow(row)


def main(argv=None):
    maybe_download_and_extract(data_dir=dataset_dir)
    train_dir = 'logs/'
    if tf.gfile.Exists(train_dir):
        tf.gfile.DeleteRecursively(train_dir)
    tf.gfile.MakeDirs(train_dir)
    TrainModel()

if __name__ == '__main__':
    tf.app.run()


cifar10_input.py

#coding:utf-8
"""Routine for decoding the CIFAR-10 binary file format."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import gzip
import os
import re
import sys
import tarfile
import urllib
import tensorflow.python.platform
from six.moves import xrange  # pylint: disable=redefined-builtin
from tensorflow.python.platform import gfile
# architecture will change and any model would need to be retrained.
IMAGE_SIZE = 24

# Global constants describing the CIFAR-10 data set.
NUM_CLASSES = 10
NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN = 50000
NUM_EXAMPLES_PER_EPOCH_FOR_EVAL = 10000

def read_cifar10(filename_queue):
  """Reads and parses examples from CIFAR10 data files.

  Recommendation: if you want N-way read parallelism, call this function
  N times.  This will give you N independent Readers reading different
  files & positions within those files, which will give better mixing of
  examples.

  Args:
    filename_queue: A queue of strings with the filenames to read from.

  Returns:
    An object representing a single example, with the following fields:
      height: number of rows in the result (32)
      width: number of columns in the result (32)
      depth: number of color channels in the result (3)
      key: a scalar string Tensor describing the filename & record number
        for this example.
      label: an int32 Tensor with the label in the range 0..9.
      uint8image: a [height, width, depth] uint8 Tensor with the image data
  """

  class CIFAR10Record(object):
    pass
  result = CIFAR10Record()

  # Dimensions of the images in the CIFAR-10 dataset.
  # See http://www.cs.toronto.edu/~kriz/cifar.html for a description of the
  # input format.
  label_bytes = 1  # 2 for CIFAR-100
  result.height = 32
  result.width = 32
  result.depth = 3
  image_bytes = result.height * result.width * result.depth  #图像的位数:3072
  # Every record consists of a label followed by the image, with a
  # fixed number of bytes for each.
  record_bytes = label_bytes + image_bytes  #标签+图像即一个样本占用的位数:3073

  # Read a record, getting filenames from the filename_queue.  No
  # header or footer in the CIFAR-10 format, so we leave header_bytes
  # and footer_bytes at their default of 0.
  reader = tf.FixedLengthRecordReader(record_bytes=record_bytes)
  result.key, value = reader.read(filename_queue)

  # Convert from a string to a vector of uint8 that is record_bytes long.
  record_bytes = tf.decode_raw(value, tf.uint8)

  # The first bytes represent the label, which we convert from uint8->int32.
  result.label = tf.cast(
      tf.slice(record_bytes, [0], [label_bytes]), tf.int32)

  # The remaining bytes after the label represent the image, which we reshape
  # from [depth * height * width] to [depth, height, width].
  depth_major = tf.reshape(tf.slice(record_bytes, [label_bytes], [image_bytes]),
                           [result.depth, result.height, result.width])
  # Convert from [depth, height, width] to [height, width, depth].
  result.uint8image = tf.transpose(depth_major, [1, 2, 0])

  return result
def _generate_image_and_label_batch(image, label, min_queue_examples,
                                    batch_size,shuffle):
  """Construct a queued batch of images and labels.

  Args:
    image: 3-D Tensor of [IMAGE_SIZE, IMAGE_SIZE, 3] of type.float32.
    label: 1-D Tensor of type.int32
    min_queue_examples: int32, minimum number of samples to retain
      in the queue that provides of batches of examples.

  Returns:
    images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
    labels: Labels. 1D tensor of [batch_size] size.
  """
  # Create a queue that shuffles the examples, and then
  # read 'FLAGS.batch_size' images + labels from the example queue.
  num_preprocess_threads = 16
  if shuffle:
    images, label_batch = tf.train.shuffle_batch(
        [image, label],
        batch_size=batch_size,
        num_threads=num_preprocess_threads,
        capacity=min_queue_examples + 3 * batch_size,
        min_after_dequeue=min_queue_examples)
  else:
    images, label_batch = tf.train.batch(
      [image, label],
      batch_size=batch_size,
      num_threads=num_preprocess_threads,
      capacity=min_queue_examples + 3 * batch_size)

  # Display the training images in the visualizer.
  tf.summary.image('images', images,max_outputs=9)

  return images, tf.reshape(label_batch, [batch_size])
def distorted_inputs(data_dir,batch_size):
  """Construct distorted input for CIFAR training using the Reader ops.

  Raises:
    ValueError: if no data_dir

  Returns:
    images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
    labels: Labels. 1D tensor of [batch_size] size.
  """
  filenames = [os.path.join(data_dir, 'data_batch_%d.bin'%i)
               for i in xrange(1,6)]
  for f in filenames:
    if not gfile.Exists(f):
      raise ValueError('Failed to find file: ' + f)

  # Create a queue that produces the filenames to read.
  filename_queue = tf.train.string_input_producer(filenames)

  # Read examples from files in the filename queue.
  read_input = read_cifar10(filename_queue)
  reshaped_image = tf.cast(read_input.uint8image, tf.float32)

  height = IMAGE_SIZE
  width = IMAGE_SIZE

  # Image processing for training the network. Note the many random
  # distortions applied to the image.

  # Randomly crop a [height, width] section of the image.
  distorted_image = tf.random_crop(reshaped_image, [height, width,3])

  # Randomly flip the image horizontally.
  distorted_image = tf.image.random_flip_left_right(distorted_image)

  # Because these operations are not commutative, consider randomizing
  # randomize the order their operation.
  distorted_image = tf.image.random_brightness(distorted_image,
                                               max_delta=63)
  distorted_image = tf.image.random_contrast(distorted_image,
                                             lower=0.2, upper=1.8)

  # Subtract off the mean and divide by the variance of the pixels.
  float_image = tf.image.per_image_standardization(distorted_image)

  #set the shapes of tensors
  float_image.set_shape([height,width,3])
  read_input.label.set_shape([1])

  # Ensure that the random shuffling has good mixing properties.
  min_fraction_of_examples_in_queue = 0.4
  min_queue_examples = int(NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN *
                           min_fraction_of_examples_in_queue)
  print ('Filling queue with %d CIFAR images before starting to train. '
         'This will take a few minutes.' % min_queue_examples)

  # Generate a batch of images and labels by building up a queue of examples.
  return _generate_image_and_label_batch(float_image, read_input.label,
                                         min_queue_examples,batch_size,
                                         shuffle=True)
def inputs(eval_data,data_dir,batch_size):
  """Construct input for CIFAR evaluation using the Reader ops.

  Args:
    eval_data: bool, indicating if one should use the train or eval data set.

  Raises:
    ValueError: if no data_dir

  Returns:
    images: Images. 4D tensor of [batch_size, IMAGE_SIZE, IMAGE_SIZE, 3] size.
    labels: Labels. 1D tensor of [batch_size] size.
  """

  if not eval_data:
    filenames = [os.path.join(data_dir,'data_batch_%d.bin' % i)
                 for i in xrange(1, 6)]
    num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN
  else:
    filenames = [os.path.join(data_dir,'test_batch.bin')]
    num_examples_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_EVAL

  for f in filenames:
    if not gfile.Exists(f):
      raise ValueError('Failed to find file: ' + f)

  # Create a queue that produces the filenames to read.
  filename_queue = tf.train.string_input_producer(filenames)

  # Read examples from files in the filename queue.
  read_input = read_cifar10(filename_queue)
  reshaped_image = tf.cast(read_input.uint8image, tf.float32)

  height = IMAGE_SIZE
  width = IMAGE_SIZE

  # Image processing for evaluation.
  # Crop the central [height, width] of the image.
  resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image,
                                                         width, height)

  # Subtract off the mean and divide by the variance of the pixels.
  float_image = tf.image.per_image_standardization(resized_image)
  #set the shapes of tensors
  float_image.set_shape([height,width,3])
  read_input.label.set_shape([1])

  # Ensure that the random shuffling has good mixing properties.
  min_fraction_of_examples_in_queue = 0.4
  min_queue_examples = int(num_examples_per_epoch *
                           min_fraction_of_examples_in_queue)

  # Generate a batch of images and labels by building up a queue of examples.
  return _generate_image_and_label_batch(float_image, read_input.label,
                                         min_queue_examples,batch_size,
                                         shuffle=False)


(2) 回复

天真 回复 jianxiong0117 2年前

非常感谢! 但有点不明白的地方是为什么这段程序运行的时候CPU的负载很高而GPU几乎没什么负责呢? 我用的是GPU的版本,跑其他的程序都没出现这样的问题

(0) 回复

jianxiong0117 回复 天真 2年前

这个就是Antares老师课程的代码,是CPU版本的,不用GPU

(0) 回复

天真 回复 jianxiong0117 2年前

CPU版的代码与单GPU版的代码的差别在哪里啊?之前课程的模型都可以自动调用GPU

(0) 回复

jianxiong0117 回复 天真 2年前

额,后面老师应该会讲的,课程还在更新中吧

(0) 回复

zcc 回复 jianxiong0117 2年前

咋不全啊,没有加L2损失

(0) 回复

菜鸟后飞 回复 jianxiong0117 2年前

贴代码的时候可以选择编辑器上的 ‘插入代码’按钮:>_ ,就可以显示代码样式了

(0) 回复

zx@123 回复 jianxiong0117 2年前

对比终于发现了错误,赞

(0) 回复

emiyashiro 回复 jianxiong0117 1年前

马克一下,多谢师兄~

(0) 回复

wudixx 回复 jianxiong0117 1年前

谢谢分享

(0) 回复

w1234863 2年前 0声望

完全抄袭老师代码,在TensorFlow1.2中跑过,没有问题,供需要的同学参考

import tensorflow as tf

import os
os.environ ['TF_CPP_MIN_LOG_LEVEL']= '2'

#算法超参数
learning_rate=0.001
trainepochs=1
batch_size=100
display_step =10



#定模型训练参数
n_input=784
n_class=10

#定义函数

def weightvariable(shape,name_str,stddev=0.1):
    initial=tf.random_normal(shape= shape,stddev=stddev,dtype=tf.float32)
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

def biasevariable(shape,name_str,stddev=0.001):
    initial=tf.random_normal(shape= shape,stddev=stddev,dtype=tf.float32)
    return tf.Variable(initial,dtype=tf.float32,name=name_str)

#定义网络卷积层函数 #2维卷积层(conv2d+biases)的封装
def conv2d(x,w,b,stride=1,padding='SAME'):
    with tf.name_scope('wx_b'):
        y=tf.nn.conv2d(x,w,strides=[1,stride,stride,1],padding=padding)
        z=tf.nn.bias_add(y,b)
        print('打印z的维度: ' ,tf.shape(z),z)
        return  z


#非线性激活层的封装
def  activation(x,activation=tf.nn.relu,name='relu'):
        with  tf.name_scope(name):
            y=activation(x)
        return y

#2维池化层pool的封装
def pool2d(x,pool=tf.nn.max_pool,k=2,stride=2):
    return pool(x,ksize=[1,k,k,1] , strides=[1,stride,stride,1],padding='VALID' )

#全连接层 wx+b 的封装

def fullconnect(x,w,b,activate=tf.nn.relu,name='relu'):
    with tf.name_scope('wx_b'):
        y=tf.matmul(x,w)
        y=tf.add(y,b)

    with  tf.name_scope(name):
        y=activate(y)
    return y

print('------开始构建计算图--------')

with  tf.Graph() .as_default():
    with tf.name_scope("inputs"):
        x_origin=tf.placeholder(tf.float32,[None,n_input],name='x_origin')
        y_true=tf.placeholder(tf.float32,[None,n_class],name='y_true')
        #把图像从n*784的张量转换成n*28*28*1的张量
        x_image=tf.reshape(x_origin,[-1,28,28,1])
    #计算图的前向推断过程
    with tf.name_scope('inference'):
        with tf.name_scope('conn2d'):
            w=weightvariable(shape=[5,5,1,16],name_str='weights')
            b=biasevariable(shape=[16],name_str='biases')
            conv_out=conv2d(x_image,w,b,stride=1,padding='VALID')
        #非线性激活层
        with tf.name_scope('activate') :
            activate_out=activation(conv_out,activation=tf.nn.relu,name='relu')
        #第一个池化层
        with tf.name_scope('pool2d'):
             pool_out=pool2d(activate_out,pool=tf.nn.max_pool,k=2,stride=2)

         #j将二维特征图变换为一维向量特征
        with  tf.name_scope('featrshape'):
            featrue=tf.reshape(pool_out,[-1,12*12*16])
        with tf.name_scope('fc_leaner'):
            w=weightvariable(shape=[12*12*16,n_class],name_str='weights')
            b=biasevariable(shape=[n_class],name_str='biases')
            ypres_logit=fullconnect(featrue,w,b,activate=tf.identity,name='identity')



    #定义损失层loss layer
    with tf.name_scope('loss'):
        cross_entropy_loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=ypres_logit))

    with tf.name_scope('training'):
 #       learning_rate =tf.placeholder(tf.float32)  #开始的网络参数,全局变量在这里美容
        opt=tf.train.GradientDescentOptimizer(learning_rate)
        trainer=opt.minimize(cross_entropy_loss)
    #定义模型评估层evaluate layer
    with tf.name_scope('evaluate')  :
        correct_pred=tf.equal(tf.argmax(ypres_logit,1),tf.argmax(y_true,1))
        accuracy =tf.reduce_mean(tf.cast(correct_pred,tf.float32))

    init=tf.global_variables_initializer()

    sess =tf.Session()
    sess.run(init)

    writer=tf.summary.FileWriter(logdir='logs/conv2d',graph=tf.get_default_graph())
    writer.close()


(0) 回复

zcc 回复 w1234863 2年前

老师的代码在哪?

(0) 回复

东京挖掘机 2年前 0声望

谢谢分享

(0) 回复

aiy 2年前 0声望

有源码吗,老师?


(0) 回复

lgprogrammer 2年前 0声望

老师使用的TensorFlow哪个版本 我的1.2版本改动后有报错

(0) 回复

熊猫人 2年前 24声望

感觉老师可以弱化算法原理讲解,大部分人可能都已经懂了。

代码讲解很细致,一步步推演和解释,非常赞,支持持续更新 ~\(≧▽≦)/~

(2) 回复

XiaoSong 2年前 4声望

求更啊老师 希望看到ResNet和Innception Net的TensorFlow实现 


(3) 回复

菜鸟后飞 2年前 414声望

欢迎大家加入社区QQ交流群  625691515, 氛围良好、共同学习、共同进步!


(0) 回复

小灰狼 2年前 0声望

对于Loss,如果直接用tf.reduce_mean(tf.pow(...,2)),是对所有维度求平均,这样是否不妥呢?我觉得应该是tf.reduce_mean(tf.reduce_sum(tf.pow(...,2), axis =1))


(0) 回复

kwrgyc 2年前 0声望

咋没找到代码呢

(0) 回复

菜鸟后飞 2年前 414声望

课程正在更新,欢迎大家提出改进意见。

(0) 回复

JJZHK 回复 菜鸟后飞 2年前

你好,请问这个系列的课程什么时候会有更新呢?老师讲的太好了,我们都很期待快点更新啊

(0) 回复