TensorFlow入门

来源:互联网 发布:owncloud php组件 编辑:程序博客网 时间:2024/05/21 17:44

关于入门

  1. 入门总要采坑,像我,开始看了tensorflow架构,跑了一些代码,随后就没有继续,而是投入到导师的项目中去了。
  2. 该来的躲不掉,项目深入无论是nlp还是ocr都要用到深度学习,开始选择了很容易上手的keras,并花了一个多礼拜的时间用来研究了正则化和优化方法的理论知识。其实cnn、rnn等说实话从入门到现在也是循环往复,每一次看的时候都是发现又有些忘了,哦原来这个点是这样的,balabala。。。理论与实践要并行啊。
  3. 说这么多废话,想告诉大家的是,重复是必须的,既然要成为一个DLer,就不怕采坑(其实还是脑子不够用)。
  4. 废话不多说了,开始正文。

1.TensorFlow架构

这里从整体结构上介绍tf架构,并针对客户端内容说的多点~毕竟我们面向的是客户端编程,底层架构和并行计算之类的目前就不涉及了(能力所限)。
  1. 基本概念与特性
    • TensorFlow基于数据流图,用于大规模分布式数值计算的开源框架。
    • 特性——跨平台、架构灵活、通用性强、良好的扩展性
      • 支持各种异构的平台,服务器,移动设备
      • 支持多CPU/GPU
      • 支持各种网络模型,具有良好的通用性
      • 具有良好的可扩展性(对op的扩展支持)
  2. 体系架构
    Tensorflow的系统结构以C-API为界,将整个系统分为前端和后端两个部分,同时也将用户层的多种类语言的代码和内核的运行时环境分离开来。

    前端系统:提供编程模型,负责构造计算图。后端系统:提供运行时环境,负责执行计算图。

这里写图片描述

  • 1) Client
    将计算定义为一个数据流图。
    用session(会话)初始化图的执行。
  • 2) Distributed Master
    根据Session.run()中的参数剥离特定子图。
    划分子图并分配给不同的进程和设备运行。
    将子图派发给Worker Services。
    Worker Service启动图片段计算的执行。
  • 3) Worker Services(每一个任务启动一个Worker Services)
    根据当前的可用硬件(CPU、GPU等),选择合适的kernel,调度图op的执行。
    不同的Worker Services之间发送和接收op结果。
  • 4) Kernel Implementions
    基于特定的设备,为特定的图op执行运算。

总结一下

1.简单来说,使用框架的编程人员主要面对的是客户端,就是你设计好了图的结构(深度神经网络的结构),最终图的计算交给后台来执行。2.从图中可以看出,后台涉及到了分布式的计算以及基于硬件的高性能计算。3.此外如果要对tensorflow框架进行扩展,就涉及到了kernel,TensorFlow的运行时包含200多个标准的OP,包括数值计算,多维数组操作,控制流,状态管理等。每一个OP根据设备类型都会存在一个优化了的Kernel实现。在运行时,运行时根据本地设备的类型,为OP选择特定的Kernel实现,完成该OP的计算。

这里再对client进行说明,毕竟入门关注的是如何使用这个问题。。。

1.Client是前端系统的主要组成部分,它是一个支持多语言的编程环境。它提供基于计算图的编程模型,方便用户构造各种复杂的计算图,实现各种形式的模型设计。目前,Tensorflow主流支持Python和C++的编程接口,并对其他编程语言接口的支持日益完善。2.Client通过Session为桥梁,连接TensorFlow后端的运行时(runtime),并启动计算图的执行过程。 3.用户构造一个图,并启动session(会话),将图的构造定义(tf.GraphDef)发送给distributed master(分布式主机)作为一个protocal buffer(Google的一种数据格式)。

2.基本使用

TensorFlow一些核心概念的理解

  1. Graph—使用图来表示计算任务,这个也是使用框架的重中之重,将计算图(神经网络结构)构造好了,扔给框架后台去执行就好了。具体地,用来表示计算的数据流图,包括一个由op-节点组成的集合,而节点又是对tensor-张量进行运算的operation。默认的在tf中,有一个默认图,调用tf.get_default_graph()可以获得。一般的,在定义运算(如tf.add())或者声明数据(tf.constant(4.0))时相当于给图增加节点,可以理解为增加数据op或者计算op。一些基本操作:

    import tensorflow as tf# 获得默认图tf.get_default_graph()# 新建一个空图tf.graph.__init__()# 新建图并作为默认图 Graph.as_default()g = tf.Graph() with g.as_default():    ....# 也可以这样写with tf.Graph().as_default() as g:    ...
  2. Session——利用会话执行图,就是对你构造好的图(神经网络结构)执行计算的交互式组件。

  3. tensor——tensorflow中所有的数据都属于一种数据结构tensor(张量)。可以看做一个n维的数组或者列表,其实就是一个numpy array。官方文档中写到 Represents a value produced by an Operation. 其实就是表示节点op的输出,这里需要注意的是表示,即tensor其实是符号标志,实际不存储值,但提供了通过会话计算这些值得方式。tensor的用途,一是用作op的输入(在op之间传递),二是在会话中执行计算图时,tenseor被传入并且它的值被计算出来。具体地,看一下这段代码:

    # 添加op构造图c = tf.constant([[1,2],[3,4]]) # 数据opd = tf.constant([[1,1],[0,1]]) # 数据ope = tf.matmul(c,d) # 计算op# 构造会话执行计算图with tf.Session() as sess:    result = sess.run(e)
    # tensor的一些属性tf.Tensor.dtype—数据类型tf.Tensor.name—名称tf.Tensor.Graph—所属的构造图tf.Tensor.op—产生tensor的optf.Tensor.eval(feed_dict=None, session=None)—在会话中评估张量,即可以执行计算返回值。具体的,调用时,需要在会话中启动图。

    这里写图片描述

  4. op——operation。图中的节点,对张量执行运算。这里要特殊注意的是,在tensorflow中强调的是节点,这里我目前的理解是,数据或者计算都是op,即可以分为数据型的op和计算型的op,边不像一般的图里表示的是计算,这里就是传递tensor的作用。

    # op的一些属性tf.Operation.nametf.Operation.type (e.g. "MatMul")tf.Operation.inputstf.Operation.outputstf.Operation.graphtf.Operation.devicetf.Operation.run(feed_dict=None, session=None)  
  5. variable-tf.Variable。变量用来维护图执行过程中的状态信息,这里可以这么理解:相比较常量,变量可以进行更新。所以这里的维护就是存储和更新,官方文档说的也是hold and update parameters.其实这里的定义可以参考tensor,即进行了统一化。这样一目了然,一个Variable,有name,数据-tensor。涉及到的操作有创建、初始化、保存、加载。

  6. tf.placeholder-占位符。其实可以理解为形参,在执行图的计算时,再传入实际的参数。

入门实战演习

这里推荐大家分析一下官方入门的代码,极客学院进行了翻译。其中我自己详细分析了字词的向量表示这个代码。自己用jupyter notebook手敲了一遍来理解,供大家参考。其中重点关注的可以是图的构造和计算的执行,以及Variable的理解(embeddings->embed->normalized_embedding->final_embeddings)。

import collectionsimport mathimport osimport randomfrom tempfile import gettempdirimport zipfileimport numpy as npfrom six.moves import urllibfrom six.moves import xrangeimport tensorflow as tf# download dataurl = 'http://mattmahoney.net/dc/'def download_file(filename, expected_bytes):    local_file = os.path.join(gettempdir(), filename)    if not os.path.exists(local_file):        local_file, _ = urllib.request.urlretrieve(url+filename, local_file)    stateinfo = os.stat(local_file)    if stateinfo.st_size == expected_bytes:        print('found & verified', filename)    else:        print(stateinfo.st_size)        raise Exception('Failed to verify' + local_file + '. can you get it with a browser?')    return local_filefilename = download_file('text8.zip', 31344016)def read_data(filename):    with zipfile.ZipFile(filename) as f:        data = tf.compat.as_str(f.read(f.namelist()[0])).split()    return datavocab = read_data(filename)print('Data size', len(vocab))# Build dictionaryvocab_size = 50000def build_dataset(words, n_words):    count = [['UNK', -1]]    count.extend(collections.Counter(words).most_common(n_words-1))    dictionary = dict()    for word, _ in count:        dictionary[word] = len(dictionary)    data = list()    unk_count = 0    for word in words:        index = dictionary.get(word, 0)        if index == 0:            unk_count += 1        data.append(index)    count[0][1] = unk_count    reversed_dict = dict(zip(dictionary.values(), dictionary.keys()))    return data, count, dictionary, reversed_dict# data - list of words code(intergers from 0 to vocab_size-1)# count - map of words to count of occurances# dictionary - map of words to codes# reversed_dict - map of codes to wordsdata, count, dictionary, reversed_dict = build_dataset(vocab, vocab_size)del vocabprint('Most common words (+UNK)', count[:5])print('Sample data', data[:10], [reversed_dict[i] for i in data[:10]])# generate training batch data_index = 0def generate_batch(batch_size, num_skips, skip_window):    global data_index    assert batch_size % num_skips == 0    assert num_skips <= 2 * skip_window    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)    if data_index + span > len(data):        data_index = 0    buffer.extend(data[data_index:data_index+span])    data_index += span    for i in range(batch_size // num_skips):        context_words = [w for w in range(span) if w != skip_window]        words_to_use = random.sample(context_words, num_skips)        for j, context_word in enumerate(words_to_use):            batch[i * num_skips + j] = buffer[skip_window]            labels[i * num_skips +j, 0] = buffer[context_word]        if data_index == len(data):            buffer[:] = data[:span]            data_index = span        else:            buffer.append(data[data_index])            data_index += 1    data_index = (data_index + len(data) - span) % len(data)    return batch, labelsbatch, labels = generate_batch(batch_size=8, num_skips=2, skip_window=1)for i in range(8):    print(batch[i], reversed_dict[batch[i]], '->', labels[i, 0], reversed_dict[labels[i, 0]])# construct skip-gram modelbatch_size = 128embedding_size = 128skip_window = 1num_skips = 2num_sampled = 64valid_size = 16valid_window = 100valid_examples = np.random.choice(valid_window, valid_size, replace=True)graph = tf.Graph()with graph.as_default():    # input data    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)    # Ops & variables pinned to cpu(or gpu)    with tf.device('/cpu:0'):        embeddings = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0))        embed = tf.nn.embedding_lookup(embeddings, train_inputs)    # nce loss    nce_weights = tf.Variable(tf.truncated_normal([vocab_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))    nce_biases = tf.Variable(tf.zeros([vocab_size]))    loss = tf.reduce_mean(        tf.nn.nce_loss(weights=nce_weights,                       biases=nce_biases,                       labels=train_labels,                       inputs=embed,                       num_sampled=num_sampled,                       num_classes=vocab_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()# train skip-gram modelnum_steps = 100001with tf.Session(graph=graph) as sess:    init.run()    print('Initialized')    average_loss = 0    for step in xrange(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 = sess.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 xrange(valid_size):                valid_word = reversed_dict[valid_examples[i]]                top_k = 8                nearest = (-sim[i, :]).argsort()[1:top_k+1]                log_str = 'Nearest to %s:' % valid_word                for k in xrange(top_k):                    close_word = reversed_dict[nearest[k]]                    log_str = '%s %s,' % (log_str, close_word)                print(log_str)    final_embeddings = normalized_embeddings.eval()# embedding visualizationdef plot_with_labels(low_dim_embs, labels, filename):    assert low_dim_embs.shape[0] >= len(labels), 'More labels than embeddings'    plt.figure(figsize=(18, 18))    for i, label in enumerate(labels):        x, y = low_dim_embs[i, :]        plt.scatter(x,y)        plt.annotate(label,                    xy=(x,y),                    xytext=(5,2),                    textcoords='offset points',                    ha='right',                    va='bottom')    plt.savefig(filename)    print(filename)    plt.show()try:    from sklearn.manifold import TSNE    import matplotlib.pyplot as plt    tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000, method='exact')    plot_only = 500    low_dim_embs = tsne.fit_transform(final_embeddings[:plot_only, :])    labels = [reversed_dict[i] for i in xrange(plot_only)]    plot_with_labels(low_dim_embs, labels, os.path.join(gettempdir(), 'tsne.png'))except ImportError as e:    print('please install sklearn, matplotlib & scipy')    print(e)

最终测试结果如下:
这里写图片描述

原创粉丝点击