educoder 练习答案 TensorFlow技术与平台应用

Pandas初体验——头歌平台答案 如果显示评测未通过,不要怀疑自己,多让平台评测几次你就通过了,当然,也有可能是因为你多打了一个空格,多换了一行,毕竟就算是我花金币换的答案也不能一次通过。第2关 了解数据处理对象-DataFrame。第1关 了解数据处理对象--Series。第6关 数据的基本操作——算术运算。第4关 数据的基本操作——排序。第5关 数据的基本操作——删除。第7关 数据的基本操作——去重。 阅读详情

1、TensorFlow初体验

一、起源

  1. 机器学习作为如今全球最为热门的计算机技术之一,可以让人们根据大量的数据来对未来的情况进行预测和判定。如今,全球科技巨头无不在在机器学习领域投入了大量的人力物力。Facebook,苹果,微软,百度,阿里巴巴,腾讯等行业巨擘无不参与其中。作为行业的领头羊 Google 公司自然也在其中。TensorFlow是 Google 多年以来内部开发建设的机器学习系统,并于2015 年面向全球进行了开源。
    TensorFlow

  2. TensorFlow 是谷歌基于 DistBelief 进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着 N 维数组,Flow(流)意味着基于数据流图的计算,TensorFlow 为张量从流图的一端流动到另一端计算过程。TensorFlow 是将复杂的数据结构传输至人工智能神经网中进行分析和处理过程的系统,可被用于语音识别、图像识别和文本处理等多项深度学习应用领域。

  3. TensorFlow 可以在 CPU 和 GPU 指令系统上运行,在操作系统方面,TensorFlow 支持 64 位的 Linux、MacOS、Windows 和移动平台Andriod 和 iOS。

  4. 截止到 2017 年九月 TensorFlow 支持 C, C++, Python 编程语言。目前,TensorFlow 的 Python 库更加易用,它提供了大量的辅助函数来简化构建图的工作,这些函数尚未被 C 和 C++ 库支持。但三种语言的会话库 (session libraries) 是一致的。本实训是基于 Python 语言开展的。

二、特性

使用 TensorFlow,我们必须明白 TensorFlow 的5点特性:

  1. 使用图 (graph) 来表示计算任务;
  2. 在被称之为会话 (session) 的上下文 (context) 中执行图;
  3. 使用 tensor 表示数据;
  4. 通过变量 (variable) 维护状态;
  5. 使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据。

三、基本框架

  1. TensorFlow 是一个编程系统, 使用图来表示计算任务。 图中的节点被称之为 op (operation 的缩写)。一个 op 获得 0 个或多个 Tensor, 然后执行计算,结果是产生 0 个或多个 Tensor。 每个 Tensor 是一个类型化的多维数组。 例如, 你可以将一小组图像集表示为一个四维浮点数数组, 这四个维度分别是 [batch, height, width, channels]。
  2. 一个 TensorFlow 图描述了计算的过程。 为了进行计算, 图必须在会话里被启动。会话将图的 op 分发到诸如 CPU 或 GPU 之类的设备上,同时提供执行 op 的方法。这些方法执行后,将产生的 tensor 返回。 在 Python 语言中, 返回的 tensor 是 numpy ndarray 对象; 在 C 和 C++ 语言中,返回的 tensor 是 tensorflow::Tensor 实例。
    一般而言,Tensor的维度或者阶数要看张量的最左边有多少个左中括号,有n个,则这个张量就是n维张量,或者n阶张量。
    TensorFlow的运算一般分为两个阶段:1.定义计算图中的所有计算,2.执行计算(会话Session

四、实现流程

  1. TensorFlow 程序通常被分成两个阶段:构建阶段和执行阶段。 在构建阶段,op 的执行步骤被描述成一个图。在执行阶段,使用会话机制执行图中的 op;
  2. 例如,通常在构建阶段创建一个图来表示和训练神经网络,然后在执行阶段反复执行图中的训练 op。
    执行会话(Session)
    会话用来执行定义好的计算。会话可以调用和管理TF的所有资源。会话用完后需要关闭释放资源。
    会话的模式有两种:


第一种、显式调用会话生成函数和关闭会话函数。

#创建一个会话
sess = tf.Session()
#运行会话得到计算结果
sess.run(result)
#关闭会话,释放资源
sess.close()

第二种:运用上下文管理器来使用会话
with tf.Session() as session:
    session.run(result)
  

五、 实验

第1关变量创建和初始化

任务描述
新建一个名为 weights 的 Tensor 变量,里面的变量名为 big_weights,并进行初始化。

相关知识
当训练模型时,用变量来存储和更新参数。变量包含张量 (Tensor)存放于内存的缓存区。建模时,它们需要被明确地初始化,模型训练后,它们必须被存储到磁盘。这些变量的值,可在之后的模型训练和分析时被加载。

本关卡介绍 TensorFlow 类中的 tf.Variable 类。

创建
当创建一个变量时,将一个张量作为初始值,传入构造函数 Variable()。TensorFlow 提供了一系列操作符来初始化张量,初始值是常量或是随机值。
我们需要指定操作符张量的 shape。变量的 shape 通常是固定的,但 TensorFlow 提供了高级的机制,用来重新调整其行列数。

# Create two variables.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")

调用 tf.Variable() 添加一些操作(Op, operation)到 graph:
一个 Variable 操作存放变量的值;
一个初始化 op 将变量设置为初始值,这事实上是一个 tf.assign 操作;
初始值的操作,例如示例中对 biases 变量的 zeros 操作也被加入了 graph。
tf.Variable 的返回值是 Python 的 tf.Variable 类的一个实例。

初始化
变量的初始化必须在模型的其它操作运行之前,先明确地完成。最简单的方法就是添加一个给所有变量初始化的操作,并在使用模型之前,首先运行那个操作;
使用 tf.global_variables_initializer() 添加一个操作,对变量做初始化。记得在完全构建好模型并加载之后,再运行那个操作。如下是代码展示:

# Create two variables.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")
...
# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()
# Later, when launching the model
with tf.Session() as sess:
  # Run the init operation.
     sess.run(init_op)
  ...
  # Use the model

用另一个变量初始化
我们有时候会需要用另一个变量的初始化值,给当前变量初始化。由于 tf.global_variables_initializer() 是并行地初始化所有变量,所以在有这种需求的情况下,我们需要尤其小心;
用其它变量的值初始化一个新的变量时,使用其它变量的 initialized_value() 属性。我们可以直接把已初始化的值,作为新变量的初始值,或者把它当做 tensor 计算得到一个值,赋予新变量。如下是代码展示:

# Create a variable with a random value.
**weights** = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="weights")
# Create another variable with the same value as 'weights'.
w2 = tf.Variable(**weights**.initialized_value(), name="w2")
# Create another variable with twice the value of 'weights'
w_twice = tf.Variable(**weights**.initialized_value() * 0.2, name="w_twice")

(1)编程要求
在右侧编辑器 Begin-End 区间补充代码,新建一个名为 weights 的 Tensor 变量,里面的变量名为 big_weights,并进行初始化。不要增删改本关的原有代码。

# -*- coding: utf-8 -*-
import tensorflow as tf

def variables_create():
    '''
    返回值:
    weights: 一个Tensor变量
    '''
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35), name="big_weights")
    # ********** End **********#
    # 返回weights
    return weights

第2关变量保存

任务描述
学习如何保存模型的变量。

相关知识
保存和加载
最简单的保存和恢复模型的方法是,使用 tf.train.Saver 对象。 tf.train.Saver 对象可以有效地保存( save )和恢复( restore )变量。 Saver 对象提供了方法,来运行节点( ops ),并定义检查点文件的读写路径。

检查点文件
变量存储在二进制文件里,里面内容主要包含从变量名到 tensor 值的映射关系。当我们创建一个 Saver 对象时,我们可以选择性地,为检查点文件中的变量挑选变量名。默认情况下,变量名为每个变量 Variable.name 属性的值。

保存变量
TensorFlow 用 tf.train.Saver() 创建一个 Saver,从而用来管理模型中的所有变量。代码示例如下:

# Create some variables.
v1 = tf.Variable(..., name="v1")
v2 = tf.Variable(..., name="v2")
...
# Add an op to initialize the variables.
init_op = tf.initialize_all_variables()
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, initialize the variables, do some work, save the
# variables to disk.
with tf.Session() as sess:
      sess.run(init_op)
  # Do some work with the model.
  ..
  # Save the variables to disk.
 save_path = saver.save(sess, "/tmp/model.ckpt")
 print "Model saved in file: ", save_path

(2)编程要求
在右侧编辑器 Begin-End 区间补充代码,新建 tf.train.Saver() 对象和 tf.Session() 对象,并进行初始化,将 tf.Session() 对象保存,保存路径为save_dir/store.ckpt。不要增删改本关的原有代码。
####测试说明

# -*- coding: utf-8 -*-

import tensorflow as tf
import time


def variables_save():
    '''
    参数:
    weights: Tensor变量
    biase:   Tensor变量
    const123:Tensor变量    
    '''
    weights=tf.Variable(tf.random_normal([784,200]),name="weights")
    biase=tf.Variable(tf.zeros([1]),name='biases')
    const123=tf.Variable(([[3]]),name="jjdaren")
    init_op=tf.global_variables_initializer()
    sess=tf.Session()
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    saver=tf.train.Saver()
    sess.run(init_op)
    save_path=saver.save(sess,'save_dir/store.ckpt')
    # ********** End **********#

    sess.close()

第3关变量恢复

任务描述
学习如何恢复模型。

相关知识
保存和加载

最简单的保存和恢复模型的方法是,使用 tf.train.Saver 对象。 tf.train.Saver 对象可以有效地保存( save )和恢复( restore )变量。 Saver 对象提供了方法,来运行节点( ops ),并定义了检查点文件的读写路径。

检查点文件
变量存储在二进制文件里,里面内容主要包含从变量名到 tensor 值的映射关系。当我们创建一个 Saver 对象时,我们可以选择性地,为检查点文件中的变量挑选变量名。默认情况下,变量名为每个变量 Variable.name 属性的值。

恢复变量
用同一个 Saver 对象来恢复变量。注意,当我们从文件中恢复变量时,不需要事先对它们做初始化。


    # Create some variables.
v1 = tf.Variable(..., name="v1")
 v2 = tf.Variable(..., name="v2")
    ...
 # Add ops to save and restore all the variables.
saver = tf.train.Saver()

# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
  # Restore variables from disk.
      saver.restore(sess, "/tmp/model.ckpt")
 print "Model restored."
  # Do some work with the model
  ...

选择存储和恢复哪些变量
如果我们不给 tf.train.Saver() 传入任何参数,那么 Saver 将处理图 (graph) 中的所有变量。其中每一个变量,都以变量创建时传入的名称被保存。在检查点文件中,明确定义变量的名称是很有用的。
有时候仅保存和恢复模型的一部分变量很有用。再举个例子,我们也许训练得到了一个 5 层神经网络,现在想训练一个 6 层的新模型,可以将之前 5 层模型的参数,导入到新模型的前 5 层中。我们可以通过给 tf.train.Saver() 构造函数,传入 Python 字典,很容易地定义需要保存的变量及对应名称:键对应使用的名称,值对应被管理的变量。

(3)编程要求
在右侧编辑器 Begin-End 区间补充代码,新建 tf.train.Saver() 对象,恢复模型,模型路径为src/step3/save_dir1/store.ckpt。不要增删改本关的原有代码。

# -*- coding: utf-8 -*-

import tensorflow as tf
import time

def variable_restore():
    '''
    参数:
    const123:Tensor变量
    
    返回值:
    final_result: 一个Tensor类型变量
    '''
    const123 = tf.Variable(([[2]]), name="jjdaren")
    sess=tf.Session()
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    saver=tf.train.Saver()
    saver.restore(sess,'src/step3/save_dir1/store.ckpt')

    # ********** End **********#
    final_result=sess.run(const123)
    sess.close()
    #返回 final_result
    return final_result

第4关占位符使用–简单乘法实现

任务描述
学习如何使用占位符。

相关知识
占位符
在 Tensorflow 中,有时候我们并不清楚具体的输入数值,但我们在图中可以先占据一个位置。这就是所谓的占位符。

input1 = tf.placeholder("float", shape=[1, 2])
input2 = tf.placeholder("float", shape=[2, 1])

这里的 input1 和 input2 并不是特定的值,相反,他们都只是一个占位符,可以在 TensorFlow 运行某一计算时,根据该占位符输入具体的值。input1 和 input2 都是一个 2 维的浮点数张量。

feed_dic

我们该如何给占位符传入具体的参数呢? 答案很简单:启动图后,使用 feed_dict 参数,将数据传入 sess.run() 函数。

sess.run(product,feed_dict={input1:[[1,3],input2:[[1],[2]]})

矩阵乘法实现
在 Tensorflow 中,矩阵相乘较为简单,如下所示:

tf.matmul(input1,input2)

在一个会话中启动图
构造阶段完成后,我们才能启动图。 启动图的第一步是,创建一个 Session 对象,如果无任何创建参数,会话构造器将启动默认图。

启动默认图.

sess = tf.Session()

#调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数. 
#上面提到, 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回
#矩阵乘法 op 的输出.
#整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的.
#函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行.
# 返回值 'result' 是一个 numpy `ndarray` 对象.
product=tf.matmul(input1,input2)
result=sess.run(product,feed_dict={input1:[[1,3]],input2:[[1],[2]]})
print result
# ==> [[ 12.]]
# 任务完成, 关闭会话.
sess.close()

Session 对象在使用完后,需要关闭以释放资源。除了显式调用 close 外, 也可以使用 “with” 代码块,来自动完成关闭动作。

with tf.Session() as sess:
     result = sess.run([product])
     print result

(4)编程要求
在右侧编辑器 Begin-End 区间补充代码,利用占位符,启动 tensorflow 图,实现 input1*input2,并将结果保存到变量 result 中。

# -*- coding: utf-8 -*-

import tensorflow as tf
import time

def placer_holders():
    '''
    参数:
    input1:占位符
    input2:占位符
    input1_value:矩阵
    input2_value:矩阵
    返回值:
    result: 一个Tensor类型变量
    '''
    input1=tf.placeholder(dtype="float32",shape=[1,2])
    input2=tf.placeholder(dtype="float32",shape=[2,1])
    input1_value=[[2,4]]
    input2_value=[[1],[2]]
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    product=tf.matmul(input1_value,input2_value)
    with tf.Session() as sess:
        result=sess.run(product)

    # ********** End **********#
    #返回result
    return  result

2、Tensorflow入门–运算

(1)Tensorflow基本运算

相关知识点

5                               # 维度为0的Tensor,即标量
[1, 2, 3, 4]                    # 维度为1的Tensor,即一维数组
[[1, 2, 3, 4], [5, 6, 7, 8]]    # 维度为2的Tensor, 即二维矩阵
[[[1, 2, 3, 4]],[[5, 6, 7, 8]]] # 维度为3的Tensor,即3维空间矩阵
定义所有计算
import tensorflow as tf             #1
a = tf.constant(5, name="input_a")  #2
b = tf.constant(3, name="input_b")  #3
c = tf.multiply(a,b, name="mul_c")  #4
d = tf.add(a,b, name="add_d")       #5
e = tf.add(c,d, name="add_e")       #6

执行会话

执行会话(Session)
会话用来执行定义好的计算。会话可以调用和管理TF的所有资源。会话用完后需要关闭释放资源。

会话的模式有两种:

第一种、显式调用会话生成函数和关闭会话函数。

#创建一个会话
sess = tf.Session()
#运行会话得到计算结果
sess.run(result)
#关闭会话,释放资源
sess.close()
第二种:运用上下文管理器来使用会话

with tf.Session() as session:
    session.run(result)

答案

# -*- coding: utf-8 -*-
import tensorflow as tf
import os

os.environ["TF_CPP_MIN_LOG_LEVEL"]='3'

def simple_func(a,b,c,d):
    '''
    返回值:
    result: 一个标量值
    '''
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    a1=tf.constant(a)
    b1=tf.constant(b)
    ab=tf.add(a1,b1).eval()
    c1=tf.constant(c)
    d1=tf.constant(d)
    cd=tf.add(c1,d1).eval()
    result=tf.multiply(ab,cd).eval()
    return result
'''
    init_op = tf.global_variables_initializer()# 必须初始化所有变量

    sess = tf.Session()
    # 使用会话得到之前计算的结果。
    sess.run(ab)
    sess.run(cd)
    sess.run(result)
    # 关闭会话使得本次运行中使用到的资源可以被释放。
    sess.close()
''' 
    # ********** End **********#

    # 返回result

a = int(input())
b = int(input())
c = int(input())
d = int(input())

init_op = tf.global_variables_initializer()#并行地初始化所有变量


with tf.Session() as sess:
    sess.run(init_op)
    print(simple_func(a,b,c,d))

(2) Tensorflow常见矩阵操作

知识点
TensorFlow常见矩阵运算
Tensorflow支持常见的矩阵运算,包括矩阵乘,点积乘,矩阵转置,矩阵求逆等。

函数 功能描述`


tf.diag(diagonal, name=None)	  返回一个给定对角值的对角tensor
tf.diag_part(input, name=None)	 功能与tf.diag函数相反,返回对角阵的对角元素
tf.t\frace(x, name=None)	          	求一个2维tensor足迹,即对角值diagonal之和
tf.transpose(a, perm=None, name=’transpose’)	矩阵转置,行列互换
tf.matmul(a, b, transpose_a=False, transpose_b=False, a_is_sparse=False, b_is_sparse=False,name=None)				矩阵乘法
tf.matrix_determinant(input, name=None)	求矩阵的行列式
tf.matrix_inverse(input, adjoint=None, name=None)	求逆矩阵

答案

# -*- coding: utf-8 -*-
import tensorflow as tf
import os

os.environ["TF_CPP_MIN_LOG_LEVEL"]='3'

def count_trace(a):
    '''
    返回值:
    result: 一个标量值
    a为int 2
    '''
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    sess=tf.Session()
    v1=tf.fill([3,3],a)
    sess.run(v1)
    '''
    print(sess.run(v1))
    [[2 2 2]
    [2 2 2]
    [2 2 2]]
    '''

    a2=tf.trace(v1)
    sess.run(a2)
    '''
    print(sess.run(a2))
    6
    '''

    v2=tf.fill([3,3],a2)
    sess.run(v2)
    '''
    print(sess.run(v2))
    [[6 6 6]
    [6 6 6]
    [6 6 6]]
    '''

    res=v1+v2
    sess.run(res)
    '''
    print(sess.run(res))
    [[8 8 8]
    [8 8 8]
    [8 8 8]]
    '''
    result1=tf.trace(res)
    result=sess.run(result1)
    '''
    print(sess.run(result))
    24
    '''
    sess.close()
    # ********** End **********#
    # 返回result
    return result

init_op = tf.global_variables_initializer()
a = int(input())

with tf.Session() as sess:
    sess.run(init_op)
    print(count_trace(a))

(3)Tensorflow数据广播机制

广播机制

一般而言,我们进行矩阵相加等计算时,会有数据格式要求,即两矩阵形状一致。但在实际处理中,我们可能会碰到形状不一致的情况,而TensorFlow的广播机制就是为了处理这个问题。广播是指让具有不同形状的张量在进行算术运算的兼容形状的过程。

# -*- coding: utf-8 -*-
import tensorflow as tf
import os

os.environ["TF_CPP_MIN_LOG_LEVEL"]='3'

def broad_cast(t):
    tensor_a = tf.constant([[1, 3], [4, 5]])
    '''
    返回值:
    result: 一个标量值
    '''
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    a = tf.constant([t,2*t])#看左边的中括号有几个,就是几维度。tensor_a是二维
    #一维向量,二维矩阵,三维空间矩阵
    '''
    a=[1 2]
    返回值:
    result: 一个标量值
    '''
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
   
    b1=tf.expand_dims(a,0)#使用0的广播尺寸。每个向量元素成为一行,并且向量对于矩阵中的每一列都进行复制。
    b2=tf.expand_dims(a,1)#使用1的广播尺寸。每个向量元素变成一列,并且向量对于矩阵中的每一行都进行复制。
    
    c1=tensor_a+b1
    c2=tensor_a+b2
    c=c1+c2
    result=tf.trace(c)

    init_op = tf.global_variables_initializer()
    with tf.Session() as sess:
        result=sess.run(result)
    # ********** End **********#
    # 返回result
    return result

init_op = tf.global_variables_initializer()

a = int(input())
with tf.Session() as sess:
    sess.run(init_op)
    print(broad_cast(a))

3、TensorFlow入门–张量运算进阶

第1关:在指定位置修改维度 - expand_dims方法与squeeze方法

知识点

a=tf.zeros([2,3,4])  #a是形状为[2,3,4]的全0数组
tf.expand_dims(a, 0) #结果是形状为[1,2,3,4]的全0数组
tf.expand_dims(a, 1) #结果是形状为[2,1,3,4]的全0数组
tf.expand_dims(a, 2) #结果是形状为[2,3,1,4]的全0数组
# -*- coding: utf-8 -*-
import tensorflow as tf

# 根据action中参数的值修改tensor的形状
# tensor是一个TensorFlow中的张量
# action是一个TensorFlow中的一维张量 (向量), 表示要对 tensor 进行操作的序列
# action的中的值 (记为x) 含义如下:
# 当x大于等于0时, 表示需要在 tensor 的第 x 维度增加一个维度.
# 当x小于0时, 表示需要去掉 tensor 的第 -x 维度 (输入数据保证合法).
# 返回修改形状后的张量.
def change(tensor,action):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    with tf.Session() as sess:
        '''
        print(sess.run(tensor)) 
        [[1. 1. 1.]
        [1. 1. 1.]]
        print(sess.run(action))
        [1]
        '''
        
        for x in action.eval():
            if x>=0:
                tensor=tf.expand_dims(tensor,x)
            else:
                tensor=tf.squeeze(tensor,-x)
        
        return sess.run(tensor)
    
    # ********** End **********#
    


第2关:合成张量 - stack方法和concat方法

知识点

t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat([t1, t2], 0)  # 结果为[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12],是个形状为[4,3]的张量。
tf.concat([t1, t2], 1)  # 结果为[[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]],是个形状为[2,6]的张量。
x = tf.constant([1, 4])
y = tf.constant([2, 5])
z = tf.constant([3, 6])
tf.stack([x, y, z],0)  # 结果为 [[1, 4], [2, 5], [3, 6]] 
tf.stack([x, y, z], 1)  # 结果为 [[1, 2, 3], [4, 5, 6]]
# -*- coding: utf-8 -*-
import tensorflow as tf

# 根据参数生成相应的张量
# 首先需要生成num个形状为shape的张量, 之后使用stack方法让这num个张量沿dim维合并. 返回合并后的结果
# 参数类型说明:
# num为正整数
# dim为整数
# shape为numpy数组
def packing(num, dim, shape):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#

    L=[]
    for i in range(0, num):
        L.append(tf.zeros(shape))#生成张量
    return tf.stack(L, dim)

    # ********** End **********#
    


第3关:判断张量是否相等- equal方法

知识点 euqal方法

判断张量是否相等
其实这里的说法略微显得有些不太严谨,因为接下来我们要讲的方法其实并不是用于判断张量是否相等的,而是用于判断张量中每个元素是否相等的。

我们首先介绍equal方法,在介绍了equal方法之后,其他的方法大家只需要看他们的名字就知道该如何使用了。

euqal方法的原型如下:

tf.math.equal(
    x,
    y,
    name=None
)
# -*- coding: utf-8 -*-
import tensorflow as tf

# 返回张量x与张量y中的相同的元素个数
def judge(x, y):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    
    a=tf.equal(x,y)
    '''
    with tf.Session() as sess:
        print(sess.run(a))
    [[ True  True False False]
    [ True False  True  True]
    [ True  True False  True]
    [False False  True  True]]
    '''
    a_reshape=tf.reshape(a,[1,-1])
    '''
    with tf.Session() as sess:
        print(sess.run(a_reshape))
        [[ True  True False False  True False  True  True  True  True False  True False False  True  True]]
    '''
    a_value=a_reshape.eval()
    
    count=0
    for x in a_value.flat:#数组的flat属性返回的是数组的迭代器,通过这个迭代器,可以一层for循环就搞定多维数组的访问
        if x:
            count=count+1
    return count
    # ********** End **********#

4、TensorFlow入门–构建神经网络

第1关:神经元与激活函数

# -*- coding: utf-8 -*-
import tensorflow as tf

# 模拟一个 M-P 神经元的工作原理
# input_value 是输入值, 类型为一维的tf.constant
# weight 是这个神经元的权重, 类型为一维的tf.constant
# threshold 是这个神经元的阈值, 类型为零维的tf.constant
# 返回值是一个浮点数
def neuron(input_value, weight, threshold):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    
    mul=input_value*weight
    y=tf.reduce_sum(mul)-threshold
    return tf.sigmoid(y).eval()#tf.sigmoid()要与eval()同用
    
    
    # ********** End **********#
    

第2关:神经元与激活函数 - tanh方法

# -*- coding: utf-8 -*-
import tensorflow as tf

# 模拟一个 M-P 神经元
class neuron(object):

    # 构造函数
    # weight为本神经元的权重,类型为一维的tf.constant
    # threshold 是这个神经元的阈值, 类型为零维的tf.constant
    def __init__(self, weight, threshold):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
        self.weight=weight
        self.threshold=threshold
    # ********** End **********#

    # 计算函数
    # input_value 是输入值, 类型为一维的tf.constant
    # 返回值是一个浮点数
    def computes(self, input_value):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#

        return tf.tanh(tf.reduce_sum(self.weight*input_value)-self.threshold).eval()
    # ********** End **********#
    

第3关:构建简单的单隐层前馈神经网络

# -*- coding: utf-8 -*-
import tensorflow as tf

# 模拟一个 M-P 神经元
class neuron(object):

    # 构造函数
    # weight为本神经元的权重,类型为一维的tf.constant
    # threshold 是这个神经元的阈值, 类型为零维的tf.constant
    def __init__(self, weight, threshold):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
        self.weight=weight
        self.threshold=threshold
    # ********** End **********#

    # 计算函数
    # input_value 是输入值, 类型为一维的tf.constant
    # 返回值是一个浮点数
    def computes(self, input_value):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
        return tf.nn.relu(tf.reduce_sum(self.weight*input_value)-self.threshold).eval()
    # ********** End **********#

# 模拟神经网络中的一层

class Dense(object):
    
    # 构造函数
    # weights 为本层中每个神经元的权重,元素类型为一维的tf.constant,weights的类型是python的列表
    # thresholds 为本层中每个神经元的权重,元素类型为零维的tf.constant,thresholds的类型是python的列表
    def __init__(self, weights, thresholds):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
        size=len(weights)
        self.neurons=[]
        for i in range(size):
            self.neurons.append(neuron(weights[i], thresholds[i]))
    # ********** End **********#

    # 计算函数
    # input_value 是输入值, 类型为一维的tf.constant
    # 返回值应为一个 1 维, 长度为n的Tensor, n是本层中神经元的数量
    def computes(self, input_value):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
        L=[]
        size=len(self.neurons)
        for i in range(size):
            L.append(self.neurons[i].computes(input_value))
        return tf.constant(L)

    # ********** End **********#

# 模拟一个简单的神经网络
# input_value是这个神经网络的输入,类型为一维的tf.constant
# wegihtsOfMiddle 是这个神经网络中间层每个神经元的权重, 元素类型为一维的tf.constant,wegihtsOfMiddle的类型是python的列表
# thresholdsOfMiddle 是这个神经网络中间层每个神经元的阈值, 元素类型为零维的tf.constant,thresholdsOfMiddle的类型是python的列表
# wegihtsOfOut 是这个神经网络输出层每个神经元的权重, 元素类型为一维的tf.constant,wegihtsOfOut 的类型是python的列表
# thresholdsOfOut 是这个神经网络输出层每个神经元的阈值, 元素类型为零维的tf.constant,thresholdsOfOut 的类型是python的列表
# 返回值是一个一维浮点数组 (注意不是Tensor),数组的长度为输出层神经元的数量

def NetWork(input_value, wegihtsOfMiddle, thresholdsOfMiddle, weightsOfOut, thresholdsOfOut):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
   
    middle=Dense(wegihtsOfMiddle, thresholdsOfMiddle)
    out=Dense(weightsOfOut, thresholdsOfOut)
    return out.computes(middle.computes(input_value)).eval()


    # ********** End **********#

5、TensorFlow入门–队列与TensorBoard操作

第1关:出队操作 - dequeue 方法

# -*- coding: utf-8 -*-
import tensorflow as tf

# 返回queue中所有张量之和
# queue是一个tensforflow.FIFOQueue
def queueSum(queue):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    #加eval()取值

    if queue.size().eval()==0:
        return 0
    ret=queue.dequeue().eval()
    while queue.size().eval()>0:#队列自减
        ret=ret+queue.dequeue().eval()
    return ret
    


    # ********** End **********#

第2关:入队 - enqueue方法

# -*- coding: utf-8 -*-
import tensorflow as tf

# 依次取出queue中各个元素, 将其与其本身相加后放回queue中
# queue是一个tensforflow.FIFOQueue
# sess是一个tensorflow.Session(), 用来执行操作
def addEach(sess, queue):
    # 请在此添加代码 完成本关任务
    # ********** Begin *********#
    for i in range(queue.size().eval()):
        x = queue.dequeue()
        y = x+x
        en_q=queue.enqueue([y])
        sess.run(en_q)
#写作queue=queue.enqueue([y])报错
        

    


    # ********** End **********#
    

6、Tensorflow入门–图与会话

(1)第1关Hello,Tensorflow

#********* Begin *********#
import tensorflow as tf
#使用tf.constant()函数在图中创建一个常量Tensor
c=tf.constant("Hello World")
# 创建一个Session
sess=tf.Session()
# 让c这个Tensor动起来,并打印c这个Tensor动起来之后的值
print(sess.run(c))
# 关闭Session
#sess.close()

#********* End *********#

(2)第2关计算图与会话

相关知识
为了完成本关任务,你需要掌握:

计算图(Graph)
会话(Session)
计算图Graph
TensorFlow是一个通过计算图的形式来表述计算的编程系统。
基于TensorFlow这个编程系统中的每一个计算都是计算图上的一个节点,而节点与节点之间的连线则代表计算之间的依赖关系。如我们需要定义一个y=wx+b的计算:
在这里插入图片描述
上图中,w,x,b为我们输入的tensor,Mul,Add表示节点之间的依赖关系。这整个就是一个计算图,我们可以理解为,计算图就是用来定义一个模型或者计算的。我们节点可以为:

常量节点tf.constant:它的value值可以为一个数值也可以为一个列表。如:

a = tf.constant(1)
b = tf.constant([1,2,3])

变量节点tf.Variable:它可以用来存储图执行过程中需要更新的量,在神经网络中用来储存权重值,创建方式如下:

v1=tf.Variable(tf.random_normal(shape=[4,3],mean=0,stddev=1),name='v1')

表示生成一个四行三列的tensor其中的值符合均值为0标准差为1的正态分布。节点名字为v1。当然还有更多其它的创建方式:

v2=tf.Variable(tf.constant(2),name='v2')
v3=tf.Variable(tf.ones([4,3]),name='v3')

…
不过值得主义的是,定义了变量节点后想要运行它需要先进行初始化:

sess.run(tf.global_variables_initializer())

占位节点tf.placeholder:placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。创建方式如下:

input1 = tf.placeholder(tf.float32)
#创建会话,喂入数据
with tf.Session() as sess:
    print(sess.run(output, feed_dict = {input1:[5.]}))

这个时候,假如我们想要计算2×3+5则可以进行如下操作:

w = tf.constant(2.)
x = tf.constant(3.)
b = tf.constant(5.)
y = tf.add(tf.multiply(w,x),b,name='y')
print(y)
>>>
Tensor("y:0", shape=(), dtype=float32)

输出结果并不是我们所意料的,这是因为,计算图只是定义了这个计算,它并没有运行起来,而想要运行起来则需要生成一个会话。

会话Session
我们已经知道计算图是用来定义一个模型或者计算的,而会话则是让这个模型或则计算运行起来,得到结果。如上一个例子,我们想要得到结果则需要进行如下操作:

sess = tf.Session()
print(sess.run(y))
>>>
11.0
进行计算后,我们可以关闭会话释放资源:

sess.close()
当然,还有另外一种创建会话的方法:

with tf.Session() as sess:
    print(sess.run(y))
>>>
11.0
这种方式不需要调用Session.close()函数来关闭会话,上下文结束时资源会自动释放。

总的来说,计算图就是定义tensor之间的依赖关系,而会话则是让这些数据flow起来。

编程要求
根据提示,在右侧编辑器补充代码,实现matmul方法。其中:

a(list):你需要将它转为相应的数据类型
b(list):你需要将它转为相应的数据类型
result(ndarray):矩阵相乘后的结果

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np

def matmul(a,b):
    '''
    a(list):矩阵a
    b(list):矩阵b
    result(ndarray):矩阵相乘结果
    '''
    #********* Begin *********#
    #常量节点tf.constant可为列表和常数
    #常量节点tf.ones可为矩阵
    #变量节点tf.Variable:它可以用来存储图执行过程中需要更新的量;在神经网络中用来储存权重值,
    v1=tf.constant(a)
    v2=tf.constant(b)

    ndarray=tf.matmul(v1,v2)


    '''
    tf.Variable 和 tf.placeholder的区别,两者都可以盛放变量,
    但在启动会话前,tf.Variable必须先被赋值和初始化,
    而tf.placeholder是需要在启动会话的时候传入值的;
    从直观上讲,tf.placeholder更加接近函数的形参。

    这是我们可以执行numpy矩阵乘法的三种方法。
    首先是使用multiple()函数, 该函数执行矩阵的逐元素乘法。
    其次是使用matmul()函数, 该函数执行两个数组的矩阵乘积。
    最后是dot()函数的使用, 该函数执行两个数组的点积。
    '''
    with tf.Session() as sess:
        result=sess.run(ndarray)
   

    #********* End *********#
    return result
    

(3) 第3关Tensorflow实现线性回归

股票数据介绍
股票原始数据如下:

在这里插入图片描述

我们的目的是利用股市收盘价、最高价与最低价的变化百分比、收盘价与开盘价的变换百分比、成交量预测未来的股市收盘价。

其中开盘价对应的数据为Adj.Open
最高价对应的数据为Adj.High
最低价对应的数据为Adj. Low
成交量对应的数据为Adj. Volume
而另外两个特征,数据表格中并没有,所以需要我们自己创建,代码如下:


import pandas as pd
df = pd.read_csv('./step3/googlestock2.csv')
# 只用到df中下面的几个字段
df = df[['Adj. Open', 'Adj. High', 'Adj. Low', 'Adj. Close', 'Adj. Volume']]
# 构造两个新的列
# HL_PCT为股票最高价与最低价的变化百分比
df['HL_PCT'] = (df['Adj. High'] - df['Adj. Close']) / df['Adj. Close'] * 100.0
# HL_PCT为股票收盘价与开盘价的变化百分比
df['PCT_change'] = (df['Adj. Close'] - df['Adj. Open']) / df['Adj. Open'] * 100.0
# 下面为真正用到的特征字段
df = df[['Adj. Close', 'HL_PCT', 'PCT_change', 'Adj. Volume']]
# 因为scikit-learn并不会处理空数据,需要把为空的数据都设置为一个比较难出现的值,这里取-9999,
df.fillna(-99999, inplace=True)
我们是要预测未来的股票收盘价格,这里定义预测天数为数据量的百分之1,然后构造出数据特征与标签:

# 定义预测列变量,它存放研究对象的标签名
forecast_col = 'Adj. Close'
# 定义预测天数,这里设置为所有数据量长度的1%
forecast_out = int(math.ceil(0.1*len(df)))
X = np.array(df.drop(['label'], 1))
#对数据进行标准化
X = preprocessing.scale(X)
#现在的收盘价为部分特征,未来的收盘价为标签
X = X[:-forecast_out]
# 通过让与Adj. Close列的数据往前移动1%行来表示
df['label'] = df[forecast_col].shift(-forecast_out)
# 抛弃label列中为空的那些行
df.dropna(inplace=True)
y = np.array(df['label'])

这时我们已经创建好数据,一共3081个样本,我们将前2481个样本用来训练,后面600个样本用来测试:

train_data,test_data = X[:-600],X[-600:]
train_label,test_label = y[:-600],y[-600:]

线性回归**

简单线性回归
在生活中,我们常常能碰到这么一种情况,一个变量会跟着另一个变量的变化而变化,如圆的周长与半径的关系,当圆的半径确定了,那么周长也就确定了。还有一种情况就是,两个变量之间看似存在某种关系,但又没那么确定,如青少年的身高与体重,他们存在一种近似的线性关系:身高/cm = 体重/kg +105

但是,并不是每个青少年都符合这个公式,只能说每个青少年的身高体重都存在这么一种近似的线性关系。这就是其实就是简单的线性回归,那么,到底什么是线性回归呢?假如我们将青少年的身高和体重值作为坐标,不同人的身高体重就会在平面上构成不同的坐标点,然后用一条直线,尽可能的去拟合这些点,这就是简单的线性回归。

简单的线性回归模型如下:

y=wx+b

其中x表示特征值(如:体重值),w表示权重,b表示偏置,y表示标签(如:身高值)。

多元线性回归
简单线性回归中,一个变量跟另一个变量的变化而变化,但是生活中,还有很多变量,可能由多个变量的变化决定着它的变化,比如房价,影响它的因素可能有:房屋面积、地理位置等等。如果我们要给它们建立出近似的线性关系,这就是多元线性回归,多元线性回归模型如下:

y=b+w1​x1+w2x2+…+wnxn
其中xi表示第i个特征值,wi表示第i个特征对应的权重,b表示偏置,y表示标签。

模型训练流程
由数据集可以知道,每一个样本有4个特征与标签,而我们要做的事就是通过这4个特征来预测标签值,我们可以构建一个多元线性回归模型,来对股票收盘价格进行预测。模型如下:
y=b+w1​x1+w2x2+…+wnxn
其中xi表示第i个特征值,wi 表示第i个特征对应的权重,b表示偏置,y表示目标房价。

而我们的目的就是找出能够正确预测的多元线性回归模型,即找出正确的参数θ。那么如何寻找呢?通常在监督学习里面都会使用这么一个套路,构造一个损失函数,用来衡量真实值与预测值之间的差异,然后将问题转化为最优化损失函数。既然损失函数是用来衡量真实值与预测值之间的差异那么很多人自然而然的想到了用所有真实值与预测值的差的绝对值来表示损失函数。不过带绝对值的函数不容易求导,所以采用MSE(均方误差)作为损失函数,公式如下:

loss= m1i=1∑m (yi −pi )2

其中p表示预测值,y表示真实值,m为样本总个数,i表示第i个样本。最后,我们再使用梯度下降来求得我们所需要的参数。

线性回归模型训练流程图如下:

关于梯度下降详细内容请点击查看

模型搭建

我们想要使用tensorflow实现线性回归,首先需要创建两个tf.placeholder用来喂入数据特征与标签:

data = tf.placeholder(tf.float32, [None, 4])
real_label = tf.placeholder(tf.float32, [None, 1])
[None, 4]表示数据有4个特征,喂入数据的样本个数待定。

然后再定义我们需要跟新的权重与偏置参数,通过上一节的内容我们直到需要用tf.Variable来定义:

weight = tf.Variable(tf.random_normal([4, 1]), dtype=tf.float32)
bias = tf.Variable(tf.ones([1]), dtype=tf.float32)

定义线性回归模型y=wx+b:

y_label = tf.add(tf.matmul(data, weight), bias)

然后构造损失函数,使用梯度下降的方法来进行训练:

#构造损失函数
loss = tf.reduce_mean(tf.square(real_label - y_label))
train = tf.train.AdamOptimizer(lr).minimize(loss)
#初始化
sess.run(tf.global_variables_initializer())
#进行训练
for i in range(n_iters):
    sess.run(train,feed_dict={data: train_data, real_label: train_label})

最后就可以对测试集数据进行预测:

test_predict = sess.run(y_label,feed_dict={data: test_data})

编程要求
根据提示,在右侧编辑器补充代码,实现线性回归方法。

# -*- coding: utf-8 -*-
import math
import numpy as np
import pandas as pd
from sklearn.preprocessing import scale
import tensorflow as tf
def preprocess_data(df):
    '''
    df(DataFrame):原始数据
    X(ndarray):处理后数据特征
    y(ndarray):处理后数据标签
    '''
    #*********Bengin*********#
    # 定义预测列变量,它存放研究对象的标签名
    forecast_col = 'Adj. Close' 
    # 定义预测天数,这里设置为所有数据量长度的1%
    forecast_out = int(math.ceil(0.1*len(df)))
    # 只用到df中下面的几个字段['Adj. Open', 'Adj. High', 'Adj. Low', 'Adj. Close', 'Adj. Volume']
    df = df[['Adj. Open', 'Adj. High', 'Adj. Low', 'Adj. Close', 'Adj. Volume']]    
    # 构造两个新的列
    # HL_PCT为股票最高价与最低价的变化百分比
    df['HL_PCT'] = (df['Adj. High'] - df['Adj. Close']) / df['Adj. Close'] * 100.0
    # HL_PCT为股票收盘价与开盘价的变化百分比
    df['PCT_change'] = (df['Adj. Close'] - df['Adj. Open']) / df['Adj. Open'] * 100.0
    # 下面为真正用到的特征字段['Adj. Close', 'HL_PCT', 'PCT_change', 'Adj. Volume']
    df = df[['Adj. Close', 'HL_PCT', 'PCT_change', 'Adj. Volume']]
    # 因为scikit-learn并不会处理空数据,需要把为空的数据都设置为一个比较难出现的值,这里取-9999,
    df.fillna(-99999, inplace=True)
    # 用label代表该字段,是预测结果
    df['label'] = df[forecast_col].shift(-forecast_out)
    #构造X
    X = np.array(df.drop(['label'], 1))   
    X = scale(X)
    X = X[:-forecast_out]
    # 抛弃label列中为空的那些行
    df.dropna(inplace=True)
    y = np.array(df['label'])
    #将标签reshape成(-1,1)
    y = y.reshape(-1,1)
    #*********End*********#
    return X,y
def tf_predict(sess,train_data,train_label,test_data,lr,n_iters):
    '''
    sess:tf.Session创建的会话
    train_data(ndarray):训练数据
    train_label(ndarray):训练标签
    test_data(ndarray):测试数据
    lr(float):学习率
    n_iters(int):训练轮数
    test_predict(ndarray):测试集预测标签
    '''
    #*********Bengin*********#
    #创建两个tf.placeholder用来喂入数据特征与标签
    data = tf.placeholder(tf.float32, [None, 4])
    real_label = tf.placeholder(tf.float32, [None, 1])


    weight = tf.Variable(tf.random_normal([4, 1]), dtype=tf.float32)
    bias = tf.Variable(tf.ones([1]), dtype=tf.float32)

    y_label = tf.add(tf.matmul(data, weight), bias)
    loss = tf.reduce_mean(tf.square(real_label - y_label))
    train = tf.train.AdamOptimizer(lr).minimize(loss)
    sess.run(tf.global_variables_initializer())
    
    for i in range(n_iters):
        sess.run(train,feed_dict={data: train_data, real_label: train_label})    
    test_predict = sess.run(y_label,feed_dict={data: test_data})
    sess.close()
    #*********End*********#
    return test_predict

7、决策树

第2关:信息熵与信息增益

import numpy as np# 计算信息熵
def calcInfoEntropy(feature, label):
    '''
    计算信息熵
    :param feature:数据集中的特征,类型为ndarray
    :param label:数据集中的标签,类型为ndarray
    :return:信息熵,类型float
    '''

    #*********** Begin ***********#
    label_set = set(label)
    #print("the type of label_set is: ",type(label_set))
    '''
    print( label_set)
    {0, 1}
    {0}
    {0, 1}
    '''
    
    result=0
    #每个标签出现的概率,得出对应的p;[[0,3/5],[1,2/5],[0,3/5]...]
    for l in label_set:#遍历集合中的每一个元素
        count = 0
        for j in range(len(label)):#print(len(label))=5
            if label[j] == l:
                count += 1
        p = count/len(label)
        result+=-p*np.log2(p)#H(X)

    return result

    #*********** End *************#


# 计算条件熵
def calcHDA(feature, label, index, value):
    '''
    计算信息熵
    :param feature:数据集中的特征,类型为ndarray
    :param label:数据集中的标签,类型为ndarray
    :param index:需要使用的特征列索引,类型为int
    :param value:index所表示的特征列中需要考察的特征值,类型为int
    :return:信息熵,类型float
    '''

    #*********** Begin ***********#
    count = 0
    sub_feature = []#list
    sub_label = []
    #print(len(feature)):5
    #print(feature):[[0, 1], [1, 0], [1, 2], [0, 0], [1, 1]] 两列分别代表性别和活跃度
    for i in range(len(feature)):#i=0/1/2/3/4
        #print(feature[i][index]) 0 1 1 0 1

        if feature[i][index] == value:#若index=1,value=
            count += 1
            sub_feature.append(feature[i])#提取出符合特征的feature
            '''
            print(feature[i])
            [1, 0]
            [1, 2]
            [1, 1]
            '''
            sub_label.append(label[i])#提取出符合特征的feature的对应标签
            '''
            print(label[i])
            1
            0
            1
            '''

    pHA = count/len(feature)
    e = calcInfoEntropy(sub_feature,sub_label)
    return pHA*e    

    #*********** End *************#


def calcInfoGain(feature, label, index):
    '''
    计算信息增益
    :param feature:测试用例中字典里的feature
    :param label:测试用例中字典里的label
    :param index:测试用例中字典里的index,即feature部分特征列的索引
    :return:信息增益,类型float
    '''

    #*********** Begin ***********#
    base_e = calcInfoEntropy(feature,label)
    #print("base_e= ",base_e):base_e=  0.5287712379549449
    f = np.array(feature)
    '''
    print(f)
    [[0 1]
    [1 0]
    [1 2]
    [0 0]
    [1 1]]
    '''
    f_set = set(f[:, index])#提取标签
    #print(f_set) :{0, 1}
    sum_HDA = 0
    for a in f_set:
        sum_HDA += calcHDA(feature, label, index, a)
    return base_e-sum_HDA
    #*********** End *************#

第3关:使用ID3算法构造决策树

import numpy as np

class DecisionTree(object):
    def __init__(self):
        #决策树模型
        self.tree = {}

    def calcInfoGain(self, feature, label, index):
        '''
        计算信息增益
        :param feature:测试用例中字典里的feature,类型为ndarray
        :param label:测试用例中字典里的label,类型为ndarray
        :param index:测试用例中字典里的index,即feature部分特征列的索引。该索引指的是feature中第几个特征,如index:0表示使用第一个特征来计算信息增益。
        :return:信息增益,类型float
        '''

        # 计算熵
        def calcInfoEntropy(label):
            '''
            计算信息熵
            :param label:数据集中的标签,类型为ndarray
            :return:信息熵,类型float
            '''

            label_set = set(label)
            result = 0
            for l in label_set:
                count = 0
                for j in range(len(label)):
                    if label[j] == l:
                        count += 1
                # 计算标签在数据集中出现的概率
                p = count / len(label)
                # 计算熵
                result -= p * np.log2(p)
            return result

        # 计算条件熵
        def calcHDA(feature, label, index, value):
            '''
            计算信息熵
            :param feature:数据集中的特征,类型为ndarray
            :param label:数据集中的标签,类型为ndarray
            :param index:需要使用的特征列索引,类型为int
            :param value:index所表示的特征列中需要考察的特征值,类型为int
            :return:信息熵,类型float
            '''
            count = 0
            # sub_feature和sub_label表示根据特征列和特征值分割出的子数据集中的特征和标签
            sub_feature = []
            sub_label = []
            for i in range(len(feature)):
                if feature[i][index] == value:
                    count += 1
                    sub_feature.append(feature[i])
                    sub_label.append(label[i])
            pHA = count / len(feature)
            e = calcInfoEntropy(sub_label)
            return pHA * e

        base_e = calcInfoEntropy(label)
        f = np.array(feature)
        # 得到指定特征列的值的集合
        f_set = set(f[:, index])
        sum_HDA = 0
        # 计算条件熵
        for value in f_set:
            sum_HDA += calcHDA(feature, label, index, value)
        # 计算信息增益
        return base_e - sum_HDA

    # 获得信息增益最高的特征
    def getBestFeature(self, feature, label):
        max_infogain = 0
        best_feature = 0
        for i in range(len(feature[0])):
            infogain = self.calcInfoGain(feature, label, i)
            if infogain > max_infogain:
                max_infogain = infogain
                best_feature = i
        return best_feature

    def createTree(self, feature, label):
        # 样本里都是同一个label没必要继续分叉了
        if len(set(label)) == 1:
            return label[0]
        # 样本中只有一个特征或者所有样本的特征都一样的话就看哪个label的票数高
        if len(feature[0]) == 1 or len(np.unique(feature, axis=0)) == 1:
            vote = {}
            for l in label:
                if l in vote.keys():
                    vote[l] += 1
                else:
                    vote[l] = 1
            max_count = 0
            vote_label = None
            for k, v in vote.items():
                if v > max_count:
                    max_count = v
                    vote_label = k
            return vote_label

        # 根据信息增益拿到特征的索引
        best_feature = self.getBestFeature(feature, label)
        tree = {best_feature: {}}
        f = np.array(feature)
        # 拿到bestfeature的所有特征值
        f_set = set(f[:, best_feature])
        # 构建对应特征值的子样本集sub_feature, sub_label
        for v in f_set:
            sub_feature = []
            sub_label = []
            for i in range(len(feature)):
                if feature[i][best_feature] == v:
                    sub_feature.append(feature[i])
                    sub_label.append(label[i])
            # 递归构建决策树
            tree[best_feature][v] = self.createTree(sub_feature, sub_label)
        return tree

    def fit(self, feature, label):
        '''
        :param feature: 训练集数据,类型为ndarray
        :param label:训练集标签,类型为ndarray
        :return: None
        '''

        #************* Begin ************#
        self.tree = self.createTree(feature, label)
        #************* End **************#

    def predict(self, feature):
        '''
        :param feature:测试集数据,类型为ndarray
        :return:预测结果,如np.array([0, 1, 2, 2, 1, 0])
        '''

        #************* Begin ************#
        result = []

        def classify(tree, feature):
            if not isinstance(tree, dict):
                return tree
            t_index, t_value = list(tree.items())[0]
            f_value = feature[t_index]
            if isinstance(t_value, dict):
                classLabel = classify(tree[t_index][f_value], feature)
                return classLabel
            else:
                return t_value

        for f in feature:
            result.append(classify(self.tree, f))

        return np.array(result)
        #************* End **************#

第5关:sklearn中的决策树

from sklearn.tree import DecisionTreeClassifier

def iris_predict(train_sample, train_label, test_sample):
    '''
    实现功能:1.训练模型 2.预测
    :param train_sample: 包含多条训练样本的样本集,类型为ndarray
    :param train_label: 包含多条训练样本标签的标签集,类型为ndarray
    :param test_sample: 包含多条测试样本的测试集,类型为ndarry
    :return: test_sample对应的预测标签
    '''
    # ************* Begin ************#

    dt = DecisionTreeClassifier(max_depth=3)#不加max_depth=3,结果正确率只有0.93
    dt.fit(train_sample, train_label)
    result=dt.predict(test_sample)
    return result
    
    # ************* End **************#
TensorFlow的实战(详细代码) TensorFlow中的计算可表示为一个有向图(计算图),其中每个运算操作为一个节点,每个节点可有任意多个输入和输出;在计算图的边中流动(flow)的数据被称为张量(tensor),tensor在计算图中flow,故命名为TensorFlow;Session是用户使用TensorFlow的交互式接口,可通过Session的Extend方法添加新的节点和边;反复执行计算图时一般的tensor不会被持续保留,Variable中的数据tensor会被保存。自编码器,即可以使用自身的高阶特征编码自己。 阅读详情

相关推荐

头歌Tensorflow核心模块

【代码】头歌Tensorflow核心模块。

m0_62710340的博客 421

Tensor变量创建-初始化-访问

文章目录一、Tensor 创建1、常量Tensor的创建1.1 Constant Value Tensor1.2 Sequences1.3 Random Tensors2、变量Tensor的创建2.1 Class tf.Variable()2.2 tf.get_variable()2.3 initializer 参数的初始化二、Tensor 的初始化及访问1 初始化2 Tensor访问参考资料 一...

潘多拉星系的专栏 3646

Tensorflow入门--图与会话

第1关:Hello,Tensorflow 本关任务:编写使用python一个Tensorlfow的Hello,World程序。 #********* Begin *********# import tensorflow as tf c = tf.constant('Hello World') # 创建一个Session sess = tf.Session() # 让c这个Tensor动起来,并打印c这个Tensor动起来之后的值 print(sess.run(c)) # 关闭Session sess.clo

Junds0的博客 1716

TensorFlow学习笔记(二):变量的创建和初始化

本节介绍Tensorflow中的变量创建和初始化操作。 初始化操作包含三种: 1. 给特定的变量单独初始化 2. 直接给所有变量初始化 3. 用其他的变量给一个变量初始化

MemoForward的博客 2248

tensorflow2模块简介

tensorflow模块简介

qq_19069557的博客 396

饥荒联机版Mod开发——modmain环境与API深度解析

本文深入解析饥荒联机版Mod开发中的modmain.lua环境与核心API,详细讲解环境表构建原理、API注册与调用时机,并提供高级开发技巧与最佳实践。通过源码分析和实际案例,帮助开发者掌握Mod开发核心技术,解决常见问题,提升开发效率与代码质量。

weixin_30312563的博客 432

educoder TensorFlow技术与平台应用

目录一、什么是TensorFlow?二、 相关知识点1、tf.constant、tf.Variable 和 tf.placeholder的区别三、代码报错四、educoderTensorFlow技术与平台应用答案第1关:Hello,Tensorflow第2关:计算图与会话 一、什么是TensorFlow? TensorFlow是一个采用数据流图(Data Flow Graphs),用于高性能数值计算的开源软件库。 Tensor(张量):即多维数组,是TensorFlow中数据表现的形式。Flow:基于数据流

Manonll的博客 561

DC-DC电源PCB布局实战:从EMI优化到热管理

本文深入探讨了DC-DC电源PCB布局的核心实战技巧。文章从分析电流环路入手,强调通过优化“黄金三角”布局以最小化环路面积,从而有效抑制EMI并提升效率。详细阐述了功率器件摆放、地线分割、敏感信号布线、电感下方铺铜策略以及热管理设计等关键步骤,为工程师提供了一套从理论到实践的完整布局指南。

z5a6b的博客 720

深度学习(四)-Tensor Flow的变量创建、初始化、保存和加载

一.创建# Create a variable. w = tf.Variable(<initial-value>, name=<optional-name>) 其中为初始值,既可以是随意值,也可以是常数 例:# Create two variables. #标准差为0.35的784*200的任意数的矩阵 weights = tf.Variable(tf.random_normal([784, 20

qq_38784375的博客 680

fdtd(时域有限差分)仿真

基础入门阶段采用 Step by step 的教学方式带着做具体的案例,在案例中学习 FDTD 应用的。的痛难点,将 FDTD 仿真引入实验当中,通过软件可视化处理有效直观的展示仿真的流程,与实验数。图像传感器,OLED 和液晶,表面计量,表面等离子体,石墨烯,太阳能电池,集成光子组件,超材。料,衍射光学和光子晶体。波,场极化,磁场,周期性结构,半球功率积分等设计解决方案,提供时域有限差分分析函数,时域。子光学传感器、热电子光探测器的光学特性研究、光学微腔宽带吸收器等多个方向的研究方法。

y2715163545的博客 5431

JavaFx之集成FontAwesomeFX与JFoenix(十五)

本文详细介绍了如何在JavaFx项目中同时集成JFoenix和FontAwesomeFX,以创建现代化、美观的桌面应用界面。通过Maven依赖配置、动态代码创建和FXML静态声明两种方式,演示了如何将JFoenix的Material Design控件与FontAwesomeFX的丰富矢量图标完美结合,并提供了实战案例展示如何构建一个功能完善的现代化工具栏。

pepsi的博客 437

表格标签—表格高级样式的设置

第1关:表格高级样式设置相关概念 任务描述 本关任务:完成一组表格高级样式设置的概念题。 相关知识 为了完成本关任务,你需要掌握:1.外边框线样式的设置,2.内部边框线的设置,3.单元格的合并。 外边框线样式属性frame 表格的外边框线的样式可用属性frame的取值来确定,frame取值与相应的样式如下: above:显示上边框 below:显示下边框 hsides:显示上下边框 vsides:显示左右边框 lhs:显示左边框 rhs:显示右边框 border:显示上下左右边框 void:不显示边框 内部

wangyongqi的博客 2302

EVM算法的Python实现

EVM(Eulerian Video Magnification,欧拉视频放大或欧拉影像放大)是一种将视频中的微小变化进行放大的算法,正如论文标题所说《Eulerian Video Magnification for Revealing Subtle Changes in the World》,该算法可以将视频中的微小变化转变为肉眼可以

flyingzhao 1万+

Tensorflow学习笔记3:变量创建,初始化

TensorFlow变量简介:创建,初始化 本教程介绍如何定义和初始化TensorFlow变量。 介绍 定义variables是必要的,因为它们包含参数。如果没有参数,则无法执行培训,更新,保存,恢复和任何其他操作。TensorFlow中定义的变量只是具有特定形状和类型的张量。必须使用值初始化张量以使其有效。在本教程中,我们将解释如何define和initialize变量。该 源代码 可在专用的G...

qq_38446366的博客 424

rosbag分析传感器数据的时间同步情况方法

ROS传感器时间同步分析流程:通过rosbaginfo初步检查bag文件信息,使用rqt_bag可视化时间线分布,采用rostopicecho或Python脚本提取各传感器时间戳并计算时间差统计值(均值/最大差/标准差),最后分析接收与采样时间延迟。量化评估同步精度,识别固定偏移或随机抖动问题,确保多传感器数据对齐,为后续融合处理提供可靠数据基础。

start_up_go的博客 201

IEC104协议学习专栏内容规划

IEC104协议的编程学习

sixtome 1109

初试tensorflow

tensorflow的使用

supe_king的博客 1607

YOLO模型轻量化实战:剪枝、量化与知识蒸馏三大技术落地详解

这篇文章结合我自己的实战经验,从原理、操作、效果、避坑四个方面,给大家讲清楚了YOLO模型轻量化的三大核心技术:剪枝、量化、知识蒸馏。先明确应用场景,再选择合适的技术组合,不要盲目追求极致压缩,要在“大小、速度、精度”之间找平衡。实战才是最好的学习方式——大家可以先拿自己的数据集试试剪枝和量化,感受一下效果,有问题可以在评论区留言。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 592

头歌操作系统实验参考答案(步骤)实验一

操作系统实验,供大家在困惑的时候参考一下,一起学习一起进步。

weixin_61712235的博客 1万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

TensorFlow入门--构建神经网络

TensorFlow入门--构建神经网络

Gosh_feifei_kris的博客 1989

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

面向对象 - 运算符重载与友元函数

拷贝构造函数:Virus(const Virus &v),拷贝到一个新的病毒对象时,并将新的病毒对象的成员变量年龄在原来病毒对象的年龄上加 1。输出函数:void Print(),输出教师信息,格式为:教师:name,编号:number,性别:sex的格式打印三个成员变量。输出函数:void Print()函数,输出学生信息,格式为:学生:name,编号:number,性别:sex。获取元素函数:int Get(int r,int c)函数,函数返回矩阵第 r 行 c 列的元素。

2303_76561497的博客 685

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

2021-07-22

任务描述 本关任务:字符串拼接。接收用户输入的两个字符串,将它们组合后输出。 相关知识 input函数() input()函数从控制台获得用户输入,无论用户在控制台输入什么内容,input()函数都以字符串类型返回结果。 name=input()//将用户输入的字符串存储到name变量中 print()函数 print()函数输出纯字符信息时,可以直接将待输出内容传递给print()函数,如: print("祖国,你好!") 当输出变量值时,需要采用格式化输出方式,通过format()方法将待输

qq_52745968的博客 778

深度学习框架头歌考试2021

第1关实现全连接层的反向传播 import numpy as np class FullyConnected: def __init__(self, W, b): r''' 全连接层的初始化。 Parameter: - W: numpy.array, (D_in, D_out) - b: numpy.array, (D_out) ''' self.W = W ...

谈论现实 2876

头歌 中国软件开源创新大赛培训答案有目录

中国软件开源创新大赛培训 深入Tensorflow 深度学习–循环神经网络 第1关 学习单步的RNN:RNNCell # -*- coding: utf-8 -*- import tensorflow as tf # 参数 a 是 BasicRNNCell所含的神经元数, 参数 b 是 batch_size, 参数 c 是单个 input 的维数,shape = [ b , c ] def creatRNNCell(a,b): # 请在此添加代码 完成本关任务 # ********** B

个人博客地址https://sun98k.github.io/ 1997

TensorFlow初体验

【代码】TensorFlow初体验。

cfy2401926342的博客 1780

TensorFlow教程之进阶指南 3.2 变量:创建、初始化、保存和加载

本文档为TensorFlow参考文档,本转载已得到TensorFlow中文社区授权。 当训练模型时,用变量来存储和更新参数。变量包含张量 (Tensor)存放于内存的缓存区。建模时它们需要被明确地初始化,模型训练后它们必须被存储到磁盘。这些变量的值可在之后模型训练和分析是被加载。 本文档描述以下两个TensorFlow类。点击以下链接可查看完整的AP...

weixin_34067980的博客 249
上一篇: educoder TensorFlow技术与平台应用
下一篇: x=np.linspace、plt.xlim和xticks的区别
@小蜗牛
博客等级 码龄8年 3009粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值