【TensorFlow学习小组】Week 4 动手任务list

深度学习

#1

##实践任务: a、 使用tf实现word2vec,并用搜狗数据集(http://www.sogou.com/labs/resource/cs.php)训练词向量(必做)截止日期:12.15 b、使用AlexNet模型,训练图片分类器,并评估准确率。(图片分类数据集:CIFAR-10 dataset 链接:http://www.cs.toronto.edu/~kriz/cifar.html)(必做)截止日期:12.15


#2

近期在做自己的课题,补上Alexnet作业~ 参考了tensorflow /model中的例子和一些博客 详细注释之后在自己的学习主题里更新…

#cifar10.py,cifar10_input.py 为tensorflow自带对cifar10数据集的预处理
#获取地址:https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10
import cifar10, cifar10_input
import tensorflow as tf
import numpy as np
import time

max_steps = 3000
batch_size = 128

#下载好的cifar10数据集所在文件夹名称
data_dir = 'cifar-10-batches-bin' 
# 如果没有下载,则需要以下命令
#cifar10.maybe_download_and_extract()

def variable_with_weight_loss(shape, stddev, wl) :
    var = tf.Variable( tf.truncated_normal(shape, stddev=stddev) ) 
    if wl is not None:
        weight_loss = tf.multiply( tf.nn.l2_loss(var), wl, name='weight_loss' )
        tf.add_to_collection( 'losses', weight_loss )
    return var

images_train, labels_train = cifar10_input.distorted_inputs( data_dir=data_dir, batch_size=batch_size )
images_test, labels_test = cifar10_input.inputs( eval_data = True, data_dir=data_dir, batch_size=batch_size )

image_holder = tf.placeholder( tf.float32, [ batch_size, 24, 24, 3 ] )
label_holder = tf.placeholder( tf.int32, [batch_size] )

weight1 = variable_with_weight_loss( shape=[5,5,3,64], stddev=5e-2, wl=0.0 )
kernel1 = tf.nn.conv2d( image_holder, weight1, [1,1,1,1], padding='SAME' )
bias1 = tf.Variable( tf.constant( 0.0, shape=[64] ) )
conv1 = tf.nn.relu( tf.nn.bias_add( kernel1, bias1 ) )
pool1 = tf.nn.max_pool(conv1, ksize = [1,3,3,1], strides=[1,2,2,1], padding='SAME' )
norm1 = tf.nn.lrn( pool1, 4, bias=1.0, alpha=0.001/9.0, beta = 0.75 )

weight2 = variable_with_weight_loss( shape=[5,5,64,64], stddev=5e-2, wl=0.0 )
kernel2 = tf.nn.conv2d( norm1, weight2, [1,1,1,1], padding='SAME' )
bias2 = tf.Variable(tf.constant( 0.1, shape=[64] ) )
conv2 = tf.nn.relu( tf.nn.bias_add(kernel2, bias2) )
norm2 = tf.nn.lrn( conv2, 4, bias=1.0, alpha=0.001/9.0, beta = 0.75 )
pool2 = tf.nn.max_pool(norm2, ksize = [1,3,3,1], strides=[1,2,2,1], padding='SAME' )

reshape = tf.reshape( pool2, [batch_size, -1] )
dim = reshape.get_shape( )[1].value
weight3 = variable_with_weight_loss( shape=[dim,384], stddev=0.04, wl=0.004 )
bias3 = tf.Variable( tf.constant( 0.1, shape=[384] ) )
local3 = tf.nn.relu( tf.matmul( reshape, weight3 ) + bias3 )

weight4 = variable_with_weight_loss( shape=[384,192], stddev=0.04, wl=0.004 )
bias4 = tf.Variable( tf.constant( 0.1, shape=[192] ) )
local4 = tf.nn.relu( tf.matmul( local3, weight4 ) + bias4 )

weight5 = variable_with_weight_loss( shape=[192,10], stddev=1.0/192, wl=0.0 )
bias5 = tf.Variable( tf.constant( 0.0, shape=[10] ) )
logits = tf.add( tf.matmul( local4, weight5 ), bias5 )

def lossFcn( logits, labels ):
    labels = tf.cast( labels, tf.int64 )
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits( logits=logits, labels=labels, name='cross_entropy_per_example' )
    cross_entropy_mean = tf.reduce_mean( cross_entropy, name = 'cross_entropy' )
    tf.add_to_collection( 'losses', cross_entropy_mean )

    return tf.add_n( tf.get_collection( 'losses' ), name = 'total_loss' )

loss = lossFcn( logits, label_holder )
train_op = tf.train.AdamOptimizer( 1e-3 ).minimize( loss )

top_k_op = tf.nn.in_top_k( logits, label_holder, 1 )
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()

tf.train.start_queue_runners()

for step in range( max_steps ):
    start_time = time.time()
    image_batch, label_batch = sess.run( [ images_train, labels_train ] )

    _, loss_value = sess.run( [train_op, loss ], feed_dict={ image_holder:image_batch, label_holder:label_batch } )
    duration = time.time() - start_time
    if step % 10 == 0:
        example_per_sec = batch_size / duration
        sec_per_batch = float( duration )

        print( ' step : %04d, loss = %.2f, %.1f example/sec; %.3f sec/batch ' %( step, loss_value, example_per_sec, sec_per_batch ) )

num_examples = 1e4
import math
num_iter = int( math.ceil( num_examples / batch_size ) )
true_count = 0
total_sample_count = num_iter * batch_size
step = 0
while step < num_iter:
    image_batch, label_batch = sess.run( [ images_test, labels_test ] )

    predictions = sess.run( [top_k_op], feed_dict = { image_holder:image_batch, label_holder:label_batch } )
    true_count += np.sum( predictions )
    step += 1

precision = 1.0 * true_count / total_sample_count 
print('precision :  %.5f' %( precision ) )

文件存放位置: cifar10下载:

由于用cpu跑的代码,所以迭代次数较少,正确率为70.9%.

运行结果:


#3

使用AlexNet模型,训练图片分类器,并评估准确率。(图片分类数据集:CIFAR-10 dataset 链接:http://www.cs.toronto.edu/~kriz/cifar.html


参考Tensorflow官方 https://github.com/tensorflow/models/tree/master/tutorials/image/cifar10/

进行修改

cifar.10

# -*- coding: utf-8 -*-
# pylint: disable=missing-docstring
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import gzip
import os
import re
import sys
import tarfile

import tensorflow.python.platform
from six.moves import urllib
import tensorflow as tf

import cifar10_input

FLAGS = tf.app.flags.FLAGS

# #基本的模型参数
tf.app.flags.DEFINE_integer('batch_size', 128,
                            """Number of images to process in a batch.""")
tf.app.flags.DEFINE_string('data_dir', '/tmp/cifar10_data',
                           """Path to the CIFAR-10 data directory.""")

# CIFAR-10数据集的全局常量
IMAGE_SIZE = cifar10_input.IMAGE_SIZE
NUM_CLASSES = cifar10_input.NUM_CLASSES
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


# 训练过程的常量。
MOVING_AVERAGE_DECAY = 0.9999     # 用于移动平均线的衰减。
NUM_EPOCHS_PER_DECAY = 350.0      # 学习速率衰减之后的时间。
LEARNING_RATE_DECAY_FACTOR = 0.1  # 学习率衰减因子。
INITIAL_LEARNING_RATE = 0.1       # 初始学习率。

# 如果一个模型使用多个GPU进行训练,则使用tower_name将所有的操作名称前缀区分操作
TOWER_NAME = 'tower'

DATA_URL = 'http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'


def _activation_summary(x):
  """Helper to create summaries for activations.

  Creates a summary that provides a histogram of activations.
  Creates a summary that measure the sparsity of activations.

  Args:
    x: Tensor
  Returns:
    nothing
  """
  # 如果这是多GPU训练,请从名称中删除“tower_ [0-9] /”会话
  # 这有助于张量板上显示的清晰度。
  tensor_name = re.sub('%s_[0-9]*/' % TOWER_NAME, '', x.op.name)
  tf.summary.histogram(tensor_name + '/activations', x)
  tf.summary.scalar(tensor_name + '/sparsity', tf.nn.zero_fraction(x))


def _variable_on_cpu(name, shape, initializer):
  """Helper to create a Variable stored on CPU memory.

  Args:
    name: name of the variable
    shape: list of ints
    initializer: initializer for Variable

  Returns:
    Variable Tensor
  """
  with tf.device('/cpu:0'):
    var = tf.get_variable(name, shape, initializer=initializer)
  return var


def _variable_with_weight_decay(name, shape, stddev, wd):
  """Helper to create an initialized Variable with weight decay.

  Note that the Variable is initialized with a truncated normal distribution.
  A weight decay is added only if one is specified.

  Args:
    name: name of the variable
    shape: list of ints
    stddev: standard deviation of a truncated Gaussian
    wd: add L2Loss weight decay multiplied by this float. If None, weight
        decay is not added for this Variable.

  Returns:
    Variable Tensor
  """
  var = _variable_on_cpu(name, shape,
                         tf.truncated_normal_initializer(stddev=stddev))
  if wd:
    weight_decay = tf.multiply(tf.nn.l2_loss(var), wd, name='weight_loss')
    tf.add_to_collection('losses', weight_decay)
  return var


def distorted_inputs():
  """Construct distorted input for CIFAR training using the Reader ops.

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

  Raises:
    ValueError: If no data_dir
  """
  if not FLAGS.data_dir:
    raise ValueError('Please supply a data_dir')
  data_dir = os.path.join(FLAGS.data_dir, 'cifar-10-batches-bin')
  return cifar10_input.distorted_inputs(data_dir=data_dir,
                                        batch_size=FLAGS.batch_size)


def inputs(eval_data):
  """Construct input for CIFAR evaluation using the Reader ops.

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

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

  Raises:
    ValueError: If no data_dir
  """
  if not FLAGS.data_dir:
    raise ValueError('Please supply a data_dir')
  data_dir = os.path.join(FLAGS.data_dir, 'cifar-10-batches-bin')
  return cifar10_input.inputs(eval_data=eval_data, data_dir=data_dir,
                              batch_size=FLAGS.batch_size)


def inference(images):
  """Build the CIFAR-10 model.

  Args:
    images: Images returned from distorted_inputs() or inputs().

  Returns:
    Logits.
  """
  # 我们使用tf.get_variable()而不是实例化所有变量
  # tf.Variable()为了在多个GPU训练运行中共享变量。
  # 如果我们只在一个GPU上运行这个模型,我们可以简化这个功能
  # 用tf.Variable()替换tf.get_variable()的所有实例。
  #
  # conv1
  with tf.variable_scope('conv1') as scope:
    kernel = _variable_with_weight_decay('weights', shape=[5, 5, 3, 64],
                                         stddev=1e-4, wd=0.0)
    conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME')
    biases = _variable_on_cpu('biases', [64], tf.constant_initializer(0.0))
    bias = tf.nn.bias_add(conv, biases)
    conv1 = tf.nn.relu(bias, name=scope.name)
    _activation_summary(conv1)

  # pool1
  pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1],
                         padding='SAME', name='pool1')
  # norm1
  norm1 = tf.nn.lrn(pool1, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75,
                    name='norm1')

  # conv2
  with tf.variable_scope('conv2') as scope:
    kernel = _variable_with_weight_decay('weights', shape=[5, 5, 64, 64],
                                         stddev=1e-4, wd=0.0)
    conv = tf.nn.conv2d(norm1, kernel, [1, 1, 1, 1], padding='SAME')
    biases = _variable_on_cpu('biases', [64], tf.constant_initializer(0.1))
    bias = tf.nn.bias_add(conv, biases)
    conv2 = tf.nn.relu(bias, name=scope.name)
    _activation_summary(conv2)

  # norm2
  norm2 = tf.nn.lrn(conv2, 4, bias=1.0, alpha=0.001 / 9.0, beta=0.75,
                    name='norm2')
  # pool2
  pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1],
                         strides=[1, 2, 2, 1], padding='SAME', name='pool2')

  # local3
  with tf.variable_scope('local3') as scope:
    # 把所有东西都移到深度,这样我们可以执行一个单一的矩阵乘法。
    dim = 1
    for d in pool2.get_shape()[1:].as_list():
      dim *= d
    reshape = tf.reshape(pool2, [FLAGS.batch_size, dim])

    weights = _variable_with_weight_decay('weights', shape=[dim, 384],
                                          stddev=0.04, wd=0.004)
    biases = _variable_on_cpu('biases', [384], tf.constant_initializer(0.1))
    local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name)
    _activation_summary(local3)

  # local4
  with tf.variable_scope('local4') as scope:
    weights = _variable_with_weight_decay('weights', shape=[384, 192],
                                          stddev=0.04, wd=0.004)
    biases = _variable_on_cpu('biases', [192], tf.constant_initializer(0.1))
    local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name=scope.name)
    _activation_summary(local4)

  # softmax, i.e. softmax(WX + b)
  with tf.variable_scope('softmax_linear') as scope:
    weights = _variable_with_weight_decay('weights', [192, NUM_CLASSES],
                                          stddev=1/192.0, wd=0.0)
    biases = _variable_on_cpu('biases', [NUM_CLASSES],
                              tf.constant_initializer(0.0))
    softmax_linear = tf.add(tf.matmul(local4, weights), biases, name=scope.name)
    _activation_summary(softmax_linear)

  return softmax_linear


def loss(logits, labels):
  """Add L2Loss to all the trainable variables.

  Add summary for for "Loss" and "Loss/avg".
  Args:
    logits: Logits from inference().
    labels: Labels from distorted_inputs or inputs(). 1-D tensor
            of shape [batch_size]

  Returns:
    Loss tensor of type float.
  """
  # Reshape the labels into a dense Tensor of
  # shape [batch_size, NUM_CLASSES].
  sparse_labels = tf.reshape(labels, [FLAGS.batch_size, 1])
  indices = tf.reshape(tf.range(FLAGS.batch_size), [FLAGS.batch_size, 1])
  concated = tf.concat([indices, sparse_labels],1)
  dense_labels = tf.sparse_to_dense(concated,
                                    [FLAGS.batch_size, NUM_CLASSES],
                                    1.0, 0.0)

  # Calculate the average cross entropy loss across the batch.
  cross_entropy = tf.nn.softmax_cross_entropy_with_logits(
    logits = logits, labels = dense_labels, name ='cross_entropy_per_example')
  cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
  tf.add_to_collection('losses', cross_entropy_mean)

  # The total loss is defined as the cross entropy loss plus all of the weight
  # decay terms (L2 loss).
  return tf.add_n(tf.get_collection('losses'), name='total_loss')


def _add_loss_summaries(total_loss):
  """Add summaries for losses in CIFAR-10 model.

  Generates moving average for all losses and associated summaries for
  visualizing the performance of the network.

  Args:
    total_loss: Total loss from loss().
  Returns:
    loss_averages_op: op for generating moving averages of losses.
  """
  # 计算所有亏损的移动平均数和总亏损。
  loss_averages = tf.train.ExponentialMovingAverage(0.9, name='avg')
  losses = tf.get_collection('losses')
  loss_averages_op = loss_averages.apply(losses + [total_loss])

  # 附上所有个人损失和全部损失的标量总结; do the
  # 计算平均版本的损失相同。
  for l in losses + [total_loss]:
    # 将每个损失命名为 '(raw)' 并命名移动平均版本的损失
    # 作为原始的损失名称。
    tf.summary.scalar(l.op.name +' (raw)', l)
    tf.summary.scalar(l.op.name, loss_averages.average(l))

  return loss_averages_op


def train(total_loss, global_step):
  """Train CIFAR-10 model.

  Create an optimizer and apply to all trainable variables. Add moving
  average for all trainable variables.

  Args:
    total_loss: Total loss from loss().
    global_step: Integer Variable counting the number of training steps
      processed.
  Returns:
    train_op: op for training.
  """
  # 影响学习率的变数。
  num_batches_per_epoch = NUM_EXAMPLES_PER_EPOCH_FOR_TRAIN / FLAGS.batch_size
  decay_steps = int(num_batches_per_epoch * NUM_EPOCHS_PER_DECAY)

  # 根据步数,以指数方式衰减学习速率。
  lr = tf.train.exponential_decay(INITIAL_LEARNING_RATE,
                                  global_step,
                                  decay_steps,
                                  LEARNING_RATE_DECAY_FACTOR,
                                  staircase=True)
  tf.summary.scalar('learning_rate', lr)

  # 生成所有损失和相关汇总的移动平均线。
  loss_averages_op = _add_loss_summaries(total_loss)

  # 计算 gradients.
  with tf.control_dependencies([loss_averages_op]):
    opt = tf.train.GradientDescentOptimizer(lr)
    grads = opt.compute_gradients(total_loss)

  # 运行 gradients
  apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)

  # 为可训练变量添加直方图。
  for var in tf.trainable_variables():
    tf.summary.histogram(var.op.name, var)

  # 为渐变添加直方图。
  for grad, var in grads:
    if grad is not None:
      tf.summary.histogram(var.op.name + '/gradients', grad)

  # 跟踪所有可训练变量的移动平均值。
  variable_averages = tf.train.ExponentialMovingAverage(
      MOVING_AVERAGE_DECAY, global_step)
  variables_averages_op = variable_averages.apply(tf.trainable_variables())

  with tf.control_dependencies([apply_gradient_op, variables_averages_op]):
    train_op = tf.no_op(name='train')

  return train_op


def maybe_download_and_extract():
  """Download and extract the tarball from Alex's website."""
  dest_directory = FLAGS.data_dir
  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,
                                             reporthook=_progress)
    print()
    statinfo = os.stat(filepath)
    print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')
    tarfile.open(filepath, 'r:gz').extractall(dest_directory)


cifar10_train.py

# -*- coding: utf-8 -*-
"""A binary to train CIFAR-10 using a single GPU.

Accuracy:
cifar10_train.py achieves ~86% accuracy after 100K steps (256 epochs of
data) as judged by cifar10_eval.py.

Speed: With batch_size 128.

System        | Step Time (sec/batch)  |     Accuracy
------------------------------------------------------------------
1 Tesla K20m  | 0.35-0.60              | ~86% at 60K steps  (5 hours)
1 Tesla K40m  | 0.25-0.35              | ~86% at 100K steps (4 hours)

Usage:
Please see the tutorial and website for how to download the CIFAR-10
data set, compile the program and train the model.

http://tensorflow.org/tutorials/deep_cnn/
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from datetime import datetime
import os.path
import time

import tensorflow.python.platform
from tensorflow.python.platform import gfile

import numpy as np
from six.moves import xrange
import tensorflow as tf

import cifar10

FLAGS = tf.app.flags.FLAGS

tf.app.flags.DEFINE_string('train_dir', '/tmp/cifar10_train',
                           """Directory where to write event logs """
                           """and checkpoint.""")
tf.app.flags.DEFINE_integer('max_steps', 1000000,
                            """Number of batches to run.""")
tf.app.flags.DEFINE_boolean('log_device_placement', False,
                            """Whether to log device placement.""")


def train():
  """Train CIFAR-10 for a number of steps."""
  with tf.Graph().as_default():
    global_step = tf.Variable(0, trainable=False)

    # 获取CIFAR-10的图像和标签。
    images, labels = cifar10.distorted_inputs()

    logits = cifar10.inference(images)

    # 计算损失。
    loss = cifar10.loss(logits, labels)

    # 构建一个图形,用一批示例和示例来训练模型
    # 更新模型参数。
    train_op = cifar10.train(loss, global_step)

    # Create a saver.
    saver = tf.train.Saver(tf.all_variables())

    summary_op = tf.summary.merge_all()

    init = tf.initialize_all_variables()

    # 开始运行
    sess = tf.Session(config=tf.ConfigProto(
        log_device_placement=FLAGS.log_device_placement))
    sess.run(init)

    # 开始 queue runners.
    tf.train.start_queue_runners(sess=sess)

    summary_writer = tf.summary.FileWriter(FLAGS.train_dir,
                                            graph_def=sess.graph_def)

    for step in xrange(FLAGS.max_steps):
      start_time = time.time()
      _, loss_value = sess.run([train_op, loss])
      duration = time.time() - start_time

      assert not np.isnan(loss_value), 'Model diverged with loss = NaN'

      if step % 10 == 0:
        num_examples_per_step = FLAGS.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))

      if step % 100 == 0:
        summary_str = sess.run(summary_op)
        summary_writer.add_summary(summary_str, step)

      # 保存模型
      if step % 1000 == 0 or (step + 1) == FLAGS.max_steps:
        checkpoint_path = os.path.join(FLAGS.train_dir, 'model.ckpt')
        saver.save(sess, checkpoint_path, global_step=step)


def main(argv=None): 
  cifar10.maybe_download_and_extract()
  if gfile.Exists(FLAGS.train_dir):
    gfile.DeleteRecursively(FLAGS.train_dir)
  gfile.MakeDirs(FLAGS.train_dir)
  train()


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


#4

最近事情实在是太多,很久没有打卡了。但是一直想着学习的。不说借口了。week4的作业a,word2vec理论并不算复杂,虽然我也记不清公式,只知道大概原理。tensorflow 官网上有word2vec的实现。语料处理是自己做的,针对搜狗数据集,只做了很简单的整理工作(在实际问题中可能还要再多做些语料处理的工作。比如去除停用词,加入分词特定词典。没有区分content 和 title的重要性,只是把他们当做了普通的信息。)。词向量模型部分参照tensorflow源码。加了一点点注释。

# coding=utf-8
import collections
import math
import random
import re

import jieba
import numpy as np
import tensorflow as tf


# 文本预处理
def strQ2B(ustring):
    """全角转半角"""
    rstring = ""
    for uchar in ustring:
        inside_code = ord(uchar)
        if inside_code == 12288:  # 全角空格直接转换
            inside_code = 32
        elif 65281 <= inside_code <= 65374:  # 全角字符(除空格)根据关系转化
            inside_code -= 65248

        rstring += chr(inside_code)
    return rstring


def data_process(data_path):
    split_word = open("../sohunews_data/jieba.txt", "w+", encoding="utf-8")
    with open(data_path, 'r', encoding='utf-8') as dp:
        for line in dp:
            contenttitle = re.findall(".*<contenttitle>(.*)</contenttitle>.*", line)
            content = re.findall(".*<content>(.*)</content>.*", line)
            if contenttitle:
                split_word.write(" ".join(jieba.cut(strQ2B(contenttitle[0].strip()).replace(" ", "。"))) + "\n")
            if content:
                split_word.write(" ".join(jieba.cut(strQ2B(content[0].strip()))) + "\n")


# use tf to load data
def load_data(data_path):
    with open(data_path, 'r', encoding="utf-8") as f:
        data = tf.compat.as_str(f.read()).split()
    return data


################################################################################
### word2vec model begin
################################################################################

words = load_data("../sohunews_data/jieba.txt")
# create the vocabulary list
vocabulary_size = 50000


# count [[word,freq]]
# dictionary (word,index)
# data [index]
# reverse_dictionary (index,word)

def build_dataset(words):
    """
    statistical analysis on words. set the most frequent top n words as the vocabulary, 
    and the others as the 'unkown' (why do this? negative sample)
    :param words: 
    :return: data # all the words,like["hello","world","nice"]
             count # [(word,freq)],like [("hello",10)]
             dictionary #{word,index},like {"hello",0}
             reverse_dictionary #{index,word} like {0,"hello"}
    """
    count = [['UNK', -1]]
    count.extend(collections.Counter(words).most_common(vocabulary_size - 1))
    dictionary = dict()
    for word, _ in count:
        dictionary[word] = len(dictionary)
    data = list()
    unk_count = 0
    for word in words:
        if word in dictionary:
            index = dictionary[word]
        else:
            index = 0
            unk_count += 1
        data.append(index)
    count[0][1] = unk_count
    reverse_dictionary = dict(zip(dictionary.values(), dictionary.keys()))
    return data, count, dictionary, reverse_dictionary


data, count, dictionary, reverse_dictionary = build_dataset(words)

del words
# print('Most common words (+UNK)', count[:5])
# print('Simple data', data[:10], [reverse_dictionary[i] for i in data[:10]])

# generate train data
data_index = 0


def generate_batch(batch_size, num_skips, skip_window):
    """
    
    :param batch_size: Number of examples for one training step.
    :param num_skips: number of samples for one word
    :param skip_window: The number of words to predict to the left and right of the target word.
    :return: 
    """
    global data_index
    assert batch_size % num_skips == 0  # ensure all the words have its whole samples in one training
    assert num_skips <= 2 * skip_window  # 2*skip_window is the largest number of samples which can be generated
    batch = np.ndarray(shape=(batch_size), dtype=np.int32)
    labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
    span = 2 * skip_window + 1
    buffer = collections.deque(maxlen=span)
    for _ in range(span):
        buffer.append(data[data_index])
        data_index = (data_index + 1) % len(data)
    for i in range(batch_size // num_skips):
        target = skip_window
        targets_to_avoid = [skip_window]
        for j in range(num_skips):
            while target in targets_to_avoid:
                target = random.randint(0, span - 1)
            targets_to_avoid.append(target)
            batch[i * num_skips + j] = buffer[skip_window]  # the feature
            labels[i * num_skips + j, 0] = buffer[target]  # the label
        buffer.append(data[data_index])
        data_index = (data_index + 1) % len(data)
        data_index = (data_index + len(data) - span) % len(data)
    return batch, labels


batch, labels = generate_batch(batch_size=8, num_skips=2, skip_window=1)
for i in range(8):
    print(batch[i], reverse_dictionary[batch[i]], '->', labels[i, 0], reverse_dictionary[labels[i, 0]])

# some parameters
batch_size = 128
embedding_size = 128
skip_window = 1
num_skips = 2
valid_size = 16
valid_window = 100
valid_examples = np.random.choice(valid_window, valid_size, replace=False)
num_sampled = 64
# start to train
graph = tf.Graph()
with graph.as_default():
    train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
    train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
    valid_dataset = tf.constant(valid_examples, dtype=tf.int32)
    with tf.device('/cpu:0'):
        embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
        embed = tf.nn.embedding_lookup(embeddings, train_inputs)
    nce_weight = tf.Variable(
        tf.truncated_normal([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))
    nce_biases = tf.Variable(tf.zeros([vocabulary_size]))

    loss = tf.reduce_mean(tf.nn.nce_loss(weights=nce_weight, biases=nce_biases, labels=train_labels, inputs=embed,
                                         num_sampled=num_sampled, num_classes=vocabulary_size))

    optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss)

    norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True))
    normalized_embeddings = embeddings / norm
    valid_embeddings = tf.nn.embedding_lookup(normalized_embeddings, valid_dataset)
    similarity = tf.matmul(valid_embeddings, normalized_embeddings, transpose_b=True)

    init = tf.global_variables_initializer()

num_steps = 100001

with tf.Session(graph=graph) as session:
    init.run()
    print("Initialized")
    average_loss = 0
    for step in range(num_steps):
        batch_inputs, batch_labels = generate_batch(batch_size, num_skips, skip_window)
        feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels}

        _, loss_val = session.run([optimizer, loss], feed_dict=feed_dict)
        average_loss += loss_val
        if step % 2000 == 0:
            if step > 0:
                average_loss /= 2000
            print("Average loss at step ", step, ": ", average_loss)
            average_loss = 0

        if step % 10000 == 0:
            sim = similarity.eval()
            for i in range(valid_size):
                valid_word = reverse_dictionary[valid_examples[i]]
                top_k = 8
                nearest = (-sim[i, :]).argsort()[1:top_k + 1]
                log_str = 'Nearest to %s:' % valid_word
                for k in range(top_k):
                    close_word = reverse_dictionary[nearest[k]]
                    log_str = '%s %s,' % (log_str, close_word)
                print(log_str)
            final_embeddings = normalized_embeddings.eval()

直观的看word2vec训练质量好不好,简单的可以看某些词的most similar words,看看他们是否在语义上具有相似性。还可以通过画一些可视化的效果图(社区里有介绍)

image

以上。


#5

先补上AlexNet训练分类器,对CIFAR-10数据集进行分类。但是准确率只有53%,不知道是不是网络结构的有问题,希望大佬们指正错误

CPU跑的代码,迭代了2000次

import pickle
import tensorflow as tf
import numpy as np

tf.logging.set_verbosity(tf.logging.INFO)


# 解压数据文件
def unpickle(file):
    with open(file, 'rb') as fo:
        dic = pickle.load(fo, encoding='bytes')
    return dic[b'data'], dic[b'labels']


def train_test_split(file):
    train_X = []
    train_y = []

    for i in range(1, 5):
        images, labels = unpickle(file + str(i))
        train_X.extend(images)
        train_y.extend(labels)

    eval_X, eval_y = unpickle(file + '5')

    return train_X, train_y, eval_X, eval_y


# 模型定义
def cnn_model_fn(features, labels, mode):
    # 输入层 32x32 ,通道3
    input_layer = tf.reshape(features['x'], [-1, 32, 32, 3])
    # 第1个卷积层 卷积核5x5,激活函数ReLU
    conv1 = tf.layers.conv2d(
        inputs=input_layer,
        filters=48,
        kernel_size=[5, 5],
        padding='SAME',
        activation=tf.nn.relu
    )
    # 第一个汇合层 大小2x2
    pool1 = tf.layers.max_pooling2d(
        inputs=conv1,
        pool_size=[2, 2],
        strides=2
    )
    # 第2个卷积层 卷积核5x5,激活函数ReLU
    conv2 = tf.layers.conv2d(
        inputs=pool1,
        filters=64,
        kernel_size=[3, 3],
        padding='SAME',
        activation=tf.nn.relu
    )
    # 第2个汇合层 大小2x2
    pool2 = tf.layers.max_pooling2d(
        inputs=conv2,
        pool_size=[2, 2],
        strides=1
    )
    # 第3个卷积层 卷积核3x3,激活函数ReLU
    conv3 = tf.layers.conv2d(
        inputs=pool2,
        filters=128,
        kernel_size=[3, 3],
        padding='SAME',
        activation=tf.nn.relu
    )
    # 第4个卷积层 卷积核3x3,激活函数ReLU
    conv4 = tf.layers.conv2d(
        inputs=conv3,
        filters=128,
        kernel_size=[3, 3],
        padding='SAME',
        activation=tf.nn.relu
    )
    # 第5个卷积层 卷积核3x3,激活函数ReLU
    conv5 = tf.layers.conv2d(
        inputs=conv4,
        filters=128,
        kernel_size=[3, 3],
        padding='SAME',
        activation=tf.nn.relu
    )
    # 第3个汇合层 大小2x2
    pool3 = tf.layers.max_pooling2d(
        inputs=conv5,
        pool_size=[2, 2],
        strides=1
    )

    pool3_flat = tf.reshape(pool3, [-1, 14 * 14 * 128])
    # 全连接层FC1
    dense1 = tf.layers.dense(pool3_flat, units=1024, activation=tf.nn.relu)
    # dropout1
    dropout1 = tf.layers.dropout(
        inputs=dense1, rate=0.5, training=mode == tf.estimator.ModeKeys.TRAIN)

    # 全连接层FC2
    dense2 = tf.layers.dense(dropout1, units=1024, activation=tf.nn.relu)
    # dropout2
    # dropout2 = tf.layers.dropout(
    #     inputs=dense2, rate=0.5, training=mode == tf.estimator.ModeKeys.TRAIN)

    # 输出层
    logits = tf.layers.dense(inputs=dense2, units=10)

    # 预测结果
    predictions = tf.argmax(input=logits, axis=1)

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

    loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

    if mode == tf.estimator.ModeKeys.TRAIN:
        optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)
        train_op = optimizer.minimize(
            loss=loss, global_step=tf.train.get_global_step())
        return tf.estimator.EstimatorSpec(
            mode=mode, loss=loss, train_op=train_op)

    eval_metrics_ops = {
        'accuracy': tf.metrics.accuracy(
            labels=labels, predictions=predictions)}
        # 'accuracy': tf.reduce_mean(tf.cast(tf.equal(labels, predictions), tf.float32))}

    return tf.estimator.EstimatorSpec(
        mode=mode, loss=loss, eval_metric_ops=eval_metrics_ops)


# 模型训练
def train():
    train_X, train_y, eval_X, eval_y = train_test_split('/home/kesci/input/cifar10/data_batch_')
    train_data = np.array(train_X, dtype=np.float32)
    train_labels = np.array(train_y, dtype=np.int32)
    eval_data = np.array(eval_X, dtype=np.float32)
    eval_labels = np.array(eval_y, dtype=np.int32)

    cifar_classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir='/home/kesci/tmp/cifar_alexnet_model')

    train_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': train_data},
        y=train_labels,
        batch_size=100,
        num_epochs=None,
        shuffle=True)
    cifar_classifier.train(
        input_fn=train_input_fn,
        steps=1000,
        # hooks=[logging_hook]
    )

    eval_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': eval_data},
        y=eval_labels,
        num_epochs=1,
        shuffle=False)
    eval_results = cifar_classifier.evaluate(input_fn=eval_input_fn)
    print('-----------------evaluate error rate------------------')
    print(eval_results)


def test():
    cifar_classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir='/home/kesci/tmp/cifar_alexnet_model')

    test_images, labels = unpickle('/home/kesci/input/cifar10/test_batch')
    eval_data = np.array(test_images, dtype=np.float32)
    eval_labels = np.array(labels, dtype=np.int32)
    eval_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': eval_data},
        y=eval_labels,
        num_epochs=1,
        shuffle=False)
    eval_results = cifar_classifier.evaluate(input_fn=eval_input_fn)
    print('-----------------test error rate------------------')
    print(eval_results)


# 预测
def predict():
    mnist_classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir='/home/kesci/tmp/cifar_alexnet_model')

    test_images, labels = unpickle('/home/kesci/input/cifar10/test_batch')
    test_data = np.array(test_images, dtype=np.float32)

    test_input_fn = tf.estimator.inputs.numpy_input_fn(
        x={'x': test_data},
        num_epochs=1,
        shuffle=False)
    predictions = mnist_classifier.predict(input_fn=test_input_fn)
    pre = [k for k in predictions]


def main(argv):
    train()
    # test()


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

#6

欢迎回归 :grin: