显示标签为“Machine learning”的博文。显示所有博文
显示标签为“Machine learning”的博文。显示所有博文

2017年7月19日星期三

tf.gather及tf.gather_nd详解

tf.gather
笔者遇到一个问题:
a = tf.Variable([[1,2,3,4,5,6,7,8,9,10]])
y = tf.Variable([2])
p = tf.gather(a,y)

》》输出:
a.shape (1, 10)
a [[ 1  2  3  4  5  6  7  8  9 10]]
y.shape (1,)
y [2]
p.shape (1, 10)
p输出出错

笔者本来以为用tf.gather可以获取出获取出相应位置的参数,但是获取的并不正确。笔者想要弄懂是为什么,探讨如下:

tf.gather

gather(
    params,
    indices,
    validate_indices=None,
    name=None
)
功能是从params中根据索引获取参数,其中indices必须是一个interger参数,产生的一个输出的tensor的shape是indices.shape+params.shpe[1:]

看完官网的解释,笔者还是不太明白,故从网上找了几个tf.gether的列子,列子如下,具体参考[1],笔者做适量修改.
例子一:
params = [0,1,2]
indices = [2]
gather = tf.gather(params,indices)
with tf.Session() as sess:
    print 'gather',gather
    print sess.run(gather)
笔者发现想这样打印的时候,就可以打印粗来了。笔者原来的目标里是二维的。

所以现在有两个解决方式,要么迭代的方法讲二维变成一维。要么通过tf.gather从二维中获取出相应值。笔者准备采用第二种方式,因为第一种方法会给代码添加多余的操作,不利于代码的直观阅读。

tf.gather_nd

 笔者在搜索过程中,查阅到tf.gather_nd函数,觉得更加适用,故改选该方法。
tf.gather_nd

gather_nd(
    params,
    indices,
    name=None
)
由于例子非常简单,笔者不在这里详述,详情参考:[2]

笔者只解决最开始遇到的问题,将其进行改正。
改正如下:
a = tf.Variable([[1,2,3,4,5,6,7,8,9,10]])
y = tf.Variable([0,2])
p = tf.gather_nd(a,y)
笔者发现这样打印出来的东西就是一个值

a = tf.Variable([[1,2,3,4,5,6,7,8,9,10]])
y = tf.Variable([[0,2]])
p = tf.gather_nd(a,y)

如果是这样改,打印出来的东西就是一个列表。
 所以到底怎么取值,完全取决于你需要什么样的数据格式。


补充:笔者在这里补充一下,笔者在一个函数中用到tf.gather_nd函数,却讲获取行号填成了[[1,*]],结果犯了错找了两个小时才找到,用的时候切忌越界。笔者心里痛痛的。






参考目录:
[1]:http://programtalk.com/python-examples/tensorflow.gather/
[2]: https://www.tensorflow.org/api_docs/python/tf/gather_nd

2017年7月18日星期二

tf.scan 详解

关于tensorflow的资料虽然多,但是针对具体函数的资料却是很少。笔者因为工作需要,想要仔细学习一下tf.scan,探索如下,仅供参考。(笔者是个tensorflow初级菜鸟,不保证理解全部正确)

tf.scan 函数定义如下

scan(
    fn,
    elems,
    initializer=None,
    parallel_iterations=10,
    back_prop=True,
    swap_memory=False,
    infer_shape=True,
    name=None
)

该函数就是一个递归函数。
我们先来看几个简单的例子:
例子一:
elems = np.array([1, 2, 3, 4, 5, 6])
sum = scan(lambda a, x: a + x, elems)
# sum == [1, 3, 6, 10, 15, 21]

在这里的scan中,由于没有initializer这个初始化参数,所以 ,在运行过程中,elems的第一个元素会被当作是初始化的值赋给a,
index     a      x     sum
1            1     #       1
2            1      2      3
3            3      3      6
4            6      4      10
5           10     5      15
6           15     6      21
故a中存储的是上一时刻的值,而x中存储的是输入的值的依次遍历


例子二:
import tensorflow as tf
import numpy as np elems = np.array([1, 2, 3, 4, 5, 6])
initializer = np.array(0)
sum_one = tf.scan(
    lambda a, x: x[0] - x[1] + a, (elems + 1, elems), initializer)
# sum_one == [1, 2, 3, 4, 5, 6]

观察这个函数,首先,它传入的值是两个list(elems+1,elems),
其中elems+1为[2,3,4,5,6,7],elems为[1,2,3,4,5,6]
a被初始化为0
故在函数执行过程中
index   a       x        sum_one
1          0    [2,1]     2-1+0=1
2          1    [3,2]     3-2+1=2
3          2    [4,3]     4-3+2=3
4          3    [5,4]           4
5          4    [6,5]           5
6          5    [7,6]           6
由于当传入多个值时,是依次取对应索引上的值,故而在elems中传入的值必须要shape相同,也很容易注意到,a保存的是前一时刻的计算结果,x中保存的是当前的输入值。

例子三:
import tensorflow as tf
import numpy as np
elems = np.array([1, 0, 0, 0, 0, 0])
initializer = (np.array(0), np.array(1))
fibonaccis = tf.scan(lambda a, _: (a[1], a[0] + a[1]), elems, initializer)
sess = tf.Session()
print initializer
print sess.run(fibonaccis)
# fibonaccis == ([1, 1, 2, 3, 5, 8], [1, 2, 3, 5, 8, 13])

index       a          x      fibonaccis
1            [0,1]      1          [1],[1]
2            [1,1]      0          [1,1],[1,2]
3            [1,2]      0          [1,1,2],[1,2,3]
4            [2,3]      0          [1,1,2,3],[1,2,3,5]
.....依次类推
在初始化值有多个的情况下,是这样调用的。

到此我们分别总结了初始化为一个列表的情况,和输入为列表的情况。现在就要来自己实现一个,初始化为多值的列表,输入同样是为一个列表的情况。(大部分代码中应该都有这样的需求)
前面的列子均来自于官网tf.scan函数下面的函数。下面的这个例子属于笔者胡编乱造,为了看下如何实现两个输入均为列表的情况

import tensorflow as tf
import numpy as np
def fn(xs,ys):
    (x1,x2) = xs
    (y1,y2) = ys
    return (y1+y2+x1,y2*y1+x2)

elems = np.array([1,2,3,4,5,6])
initializer = (np.array(0),np.array(1))
outcome = tf.scan(fn,(elems+1,elems),initializer)

sess = tf.Session()
print "outcome",sess.run(outcome)

#outcome (array([ 3,  8, 15, 24, 35, 48]), array([  3,   9,  21,  41,  71, 113]))

让我们来看看它是如何生成序列的
首先,我们在scan中设置了elmes和initializer,
在调用函数时,xs中为[[2,3,4,5,6,7],[1,2,3,4,5,6]]
                      ys中为[0,1]
下面的xs和ys仅表示在某一时刻下的值
index       xs        ys        outcome
1            [0,1]    [2,1]      [3],[3]
2            [3,3]    [3,2]      [3,8],[3,9]
3            [8,9]    [4,3]      [3,8,15],[3,9,21]
...
依次类推

故而,对于tf.scan函数,可以总结为以下几点
1.当没有赋初始值时,tf.scan会把elems的第一个元素作为初始化值,故,elems在initializer没有值时一定要有值。
2.initializer参数和elems参数都可以有若干个。
3.initializer中的值只在第一轮中用到,然后它就用来存储每次计算出来的值,所以,初始化值和输出的中间结果个数一定要想等。

到这里,tf.scan常用参数大家应该都已经很清楚了,笔者反正感觉应该可以开始写代码了。

加油↖(^ω^)↗
于7月19日两点,笔者成功的把tf.scan用在了自己的程序上,并且完美的实现了功能,点个赞。


补充:在实践过程中 ,你会遇到一个问题。就是有些参数被用来初始化参数,但是却并不被返回。而有些值则是在调用函数中被生成,并且会被返回,遇到这样的情况,我们应该怎么做呢?

通过探索,在tf.scan中并没有这个功能,对于那种用作初始化并且不会在循环中改变的值,我们只能用self.* = *的形式传入。我在tf的相关函数中,均没有看到对这种问题的解决方法。
但在这里我不能妄下定论,只是笔者没有找到,因为看到这篇文章并且知道的大神可以给予指正















2017年7月12日星期三

TensorFlow编程手册:Tensor Ranks, Shapes, and Types

    TensorFlow中使用tensor数据结构代表所有的数据,你可以把tensorflow中的tensor想象为n维的数组或者list。一个tensor具有静态的type和动态的维度,在computation图中,只有tensors的值可以在nodes中传递。

1.Rank
维度,是一个number值
如: t =[[1,2,3],[4,5,6],[7,8,9]]

TensorFlow编程手册:sharing variables

(本文来自于 官网,仅供学习使用,文中[*]表示见解释【*】)
目前为止,你已经能 create, initialize, save and load single variables了。但是当建立复杂的网络时,你需要共享大量的权值并且也许你需要一次性初始化它们,下面 介绍tf.variable_scope()和tf.get_variable().

1.想象你创建一个具有两个卷积层的网络,如果使用tf.Variable,模型将会是下面的样子
def my_image_filter(input_images):
    conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
        name="conv1_weights")
    conv1_biases = tf.Variable(tf.zeros([32]), name="conv1_biases")
    conv1 = tf.nn.conv2d(input_images, conv1_weights,
        strides=[1, 1, 1, 1], padding='SAME')
    relu1 = tf.nn.relu(conv1 + conv1_biases)

    conv2_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
        name="conv2_weights")
    conv2_biases = tf.Variable(tf.zeros([32]), name="conv2_biases")
    conv2 = tf.nn.conv2d(relu1, conv2_weights,
        strides=[1, 1, 1, 1], padding='SAME')
    return tf.nn.relu(conv2 + conv2_biases)
可以看出,模型一旦变得更复杂,就会造成更多的复杂性,即使现在只有两层,也已经有了4个不同的变量。
当你想重用这个模型的时候,问题就会出现了。假定你想应用你的模型到2个不同的图image1和image2时,你想要它们通过相同的模型(并且带有相同的参数),你可以两次运行my_image_filter(),但是他创建了2个集合,每个集合四个变量,总共8个变量。
#
#first call creates one set of 4 varaibles
result = my_image_filter(image)
#another set of 4 variables is creates in the second call
result2 = my_image_filter(image2)

2.下面有一个共享变量的方法
variables_dict = {
    "conv1_weights" :tf.Variable(tf.random_normal([5,5,32,32])[1],
            name="conv1_weights")
    "conv1_biases" : tf.Variable(tf.zeros([32]),name="conv1_biases")
     .....
}

def my_image_filter(input_images, variables_dict):
    conv1 = tf.nn.conv2d(input_images, variables_dict["conv1_weights"],
        strides=[1, 1, 1, 1], padding='SAME')
    relu1 = tf.nn.relu(conv1 + variables_dict["conv1_biases"])

    conv2 = tf.nn.conv2d(relu1, variables_dict["conv2_weights"],
        strides=[1, 1, 1, 1], padding='SAME')
    return tf.nn.relu(conv2 + variables_dict["conv2_biases"])

# Both calls to my_image_filter() now use the same variables
result1 = my_image_filter(image1, variables_dict)
result2 = my_image_filter(image2, variables_dict)
虽然方便,但在代码之外创建如上所述的变量会破坏封装:

     构建图形的代码必须记录要创建的变量的名称,类型和形状。
     代码更改时,调用者可能必须创建更多或更少或不同的变量。

解决问题的一种方法是使用类创建一个模型,其中类负责管理所需的变量。 对于较轻的解决方案,不涉及类,TensorFlow提供了一个variable scope机制,允许在构建图形时轻松共享命名变量。

3.variable scope example
TF中的Variable scope机制包括两个主要功能:
    tf.get_variable(<name>,<shape>,<initializer>):创建或返回具有给定名称的变量。
    tf.variable_scope(<scope_name>):管理传递给tf.get_variable()的名称的名称空间
函数tf.get_variable()被用于获取或创建一个variable而不是直接调用tf.Variable, 它使用initializer而不是直接传递值,如在tf.Variable中。 一个initializer是一个函数,它获取shape,并提供一个具有该shape的张量。 以下是TensorFlow中的一些initializer:
     tf.constant_initializer(value)将所有内容初始化为提供的值,
     tf.random_uniform_initializer(a,b) initializes uniformly from [a, b],
     tf.random_normal_initializer(mean,stddev)从给定的平均值和标准偏差的正态分布初始化。

tf.get_variable到底是如何解决我们上述提到的问题的呢?首先,让我们重构代码,讲卷积的代码写到一个函数里,称为conv_relu.
def conv_relu(input, kernel_shape, bias_shape):
    # Create variable named "weights".
    weights = tf.get_variable("weights", kernel_shape,
        initializer=tf.random_normal_initializer())
    # Create variable named "biases".
    biases = tf.get_variable("biases", bias_shape,
        initializer=tf.constant_initializer(0.0))
    conv = tf.nn.conv2d(input, weights,
        strides=[1, 1, 1, 1], padding='SAME')
    return tf.nn.relu(conv + biases)

此功能使用短名称“weights”和“biases”。 我们希望将它用于conv1和conv2,但变量需要具有不同的名称。 这就是tf.variable_scope()发挥作用的地方:它指定变量的命名空间。

def my_image_filter(input_images):
    with tf.variable_scope("conv1"):
        # Variables created here will be named "conv1/weights", "conv1/biases".
        relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])
    with tf.variable_scope("conv2"):
        # Variables created here will be named "conv2/weights", "conv2/biases".
        return conv_relu(relu1, [5, 5, 32, 32], [32])

现在,让我们看看当我们调用my_image_filter()两次时会发生什么
result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Raises ValueError(... conv1/weights already exists ...)
为了共享他们,你需要通过设定reuse_variables()来指定他们
with tf.variable_scope("image_filters") as scope:
    result1 = my_image_filter(image1)
    scope.reuse_variables()
    result2 = my_image_filter(image2)
这是一个共享权重的好方法

4.Variable scope是怎么工作的
为了理解variable scope是怎么工作的,首先要理解tf.get_variable()是怎么工作的,调用如下:
v = tf.get_variable(name, shape, dtype, initializer)
这种调用的出现有两种情况。
case1: 创建新的变量,此时tf.get_variable_scope().resuse == False
在这种情况下,v将是新创建的具有shape和data type的tf.Variable。 创建的变量的全名将被设置为当前变量范围名称+提供的名称,并且将执行检查以确保没有存在此全名的变量。 如果具有此全名的变量已存在,则该函数将引发ValueError。 如果创建了一个新变量,它将被初始化为值initializer(shape)。 例如:

with tf.variable_scope("foo"):
    v = tf.get_variable("v",[1])
assert v.name == "foo/v:0"

case 2:变量已经存在,此时tf.get_variable_scope().resuse ==True
with tf.variable_scope("foo")
    v = tf.get_variable("v",[1])
with tf.variable_scope("foo",reuse=True)
    v1 = tf.get_variable("v",[1])
assert v1 is v


4.1 Basics of tf.variable_scope()
知道get_variable如何工作之后,会让你更容易理解variable scope. variable scope的主要功能是携带将用作变量名称的前缀的名称和重用标志来区分上述两种情况。 嵌套变量作用域以类似于目录的工作方式追加其名称:
variable_scope就相当于给变量加前缀,为了区分,相加几个就加几个
with tf.variable_scope("foo"):
    with tf.variable_scope("bar"):
        v = tf.get_variable("v", [1])
assert v.name == "foo/bar/v:0"


[1]解释关于random_normal函数:http://blog.csdn.net/youngdreamnju/article/details/53993719




























TensorFlow 编程手册: Variables: Creation, Initialization, Saving, and Loading

(本文来自官方手册,笔者为初学者,记下以作学习)
当你训练一个模型的时候,你可以使用variables去存放和更新参数。Variables就是包含tensor的内存缓冲区。你必须明确的初始化,他们能够在训练期间或训练结束被保存到磁盘。之后,你可以恢复他们的值去训练和分析模型。
下面列出了本文引用了TF的类,
     The tf.Variable class
     The tf.train.Saver class


1.Creation
当调用tf.Variable的时候,就在向图中添加op.

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


2.Initialization
变量的初始化必须在运行其他操作前运行,最方便的方法是加一个op去run所有的变量初始化,如下所示:
#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 varaibles
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
    ...

2.1 Initialization from another Variable
有时候你要用另一个变量的值来初始化变量,由于用tf.global_variables_initializer()初始化所有的变量,所有使用的时候必须小心。这时候要用到initialized_value()属性
# 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() * 2.0, name="w_twice")


3.Saving and restoring
保存和恢复模型的最简单方法是使用tf.train.Saver对象。 构造函数将图形中的所有变量或指定列表的图形添加到图形中。 保护对象提供了运行这些操作的方法,指定检查点文件写入或读取的路径。
 请注意,要恢复没有图形的模型检查点,必须首先从元图形文件导入图形(典型扩展名为.meta)。 这是通过tf.train.import_meta_graph完成的,而tf.train.import_meta_graph又返回一个可以执行还原的Saver。

 3.1.Checkpoint Files
 变量保存在二进制文件中,大致包含从变量名到张量值的映射。创建Saver对象时,您可以选择为检查点文件中的变量名称。 默认情况下,它为每个变量使用tf.Variable.name属性的值。要了解检查点中的哪些变量,可以使用inspect_checkpoint库,特别是print_tensors_in_checkpoint_file函数。

 3.2 Saving Variables
通过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.global_variables_initializer()

#Add ops to save and restore all the variable
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:%s" %save_path)

3.3 Restoring Variables
同样的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
  ...

 3.4 Choosing which variables to save and restore

2017年7月11日星期二

tensorflow初学习

(参考tensotflow官方文档,只做个人学习所用,原文来自于:https://www.tensorflow.org/get_started/get_started)
1.导入tensorflow (tensorflow的所有资源)
   import tensorflow as tf

2.tensorflow流程

   2.1 Building the computational graph
   2.2 Running the computational graph

3.开始,创建一个tf的常量,如果定义为常量,则初始化过后,他们的值就不能再被改变
  node1 = tf.constant(3.0,dtype=tf.float32)
  node2 = tf.constant(4.0) #also tf.float32
  print(node1,node2)

 它只会输出节点信息,而不会输出结点中的值,如果我们想要他输出实际结点中的值,必须在session中运行计算图。会话封装了tensorflow运行时的控制和状态。
下面创建一个session,并调用他的run方法
  sess = tf.Session()
  print(sess.run([node1,node2]))

>>[3.0,4.0]

4.创建更复杂的图
  node3 = tf.add(node1,node2)
  print("node3:",node3)
  print("sess.run(node3):",sess.run(node3))



>>node3: Tensor("Add:0",shape(),dtype=float32)
>>sess.run(node3):7.0

5.问题来了,如果你想输入输出的时候肿么办呢?用placeholders
  a = tf.placeholder(tf.float32)
  b = tf.placeholder(tf.float32)
  adder_node = a + b   # + is equal to tf.add(a,b)

上面三行就类似于定义了一个函数,这个函数接受两个参数
如何用:
 print(sess.run(adder_node,{a:3,b:4.5}))
 print(sess.run(adder_node,{a:[1,3],b:[2,4]}))
>>7.5
>>[3,7]



 6.让图变得更复杂
add_and_tripe = add_node * 3
print(sess.run(add_and_triple),{a:3,b:4.5})


 7.在机器学习中,我们通常会想要一个可以接受任意输入的模型,比如上面的一个。 为了使模型可训练,我们需要能够修改图形以获得具有相同输入的新输出。 变量允许我们向图表添加可训练的参数。 它们的构造类型和初始值:
  W = tf.Variable([.3],dtype=tf.float32)
   b = tf.Variable([-.3],dtype=tf.float32)
   x = tf.placeholder(tf.float32)
   linear_model = W*x + b 

当定义tf.constant的时候,常量直接被初始化并且值不会再发生变化;但是当变量被声明时,调用tf.Variable,这时候变量没有被赋值,为了给变量赋值,必须调用下面指定操作

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

在我们运行sess.run(init)之前,变量都是未被赋值的(就是值已经定义好了,但是却没有给定赋值),运行过后因为x 是一个placeholder,我们可以评估linear_model
  print(sess.run(linear_model,{x:[1,2,3,4]}))

 >>[ 0.          0.30000001  0.60000002  0.90000004]

损失函数测量当前模型与提供的数据之间的距离。 我们将使用线性回归的标准损耗模型,它将当前模型和提供的数据之间的三角形的平方相加。 linear_model - y创建一个向量,其中每个元素都是对应的示例的错误增量。 我们称tf.square为该错误。 然后,我们求和所有平方误差,创建一个单一的标量,使用tf.reduce_sum抽象出所有示例的错误:

 y = tf.placeholder(tf.float32)
 squared_deltas = tf.square(linear_model - y)
 loss = tf.reduce_sum(squared_deltas)
 print(sess.run(loss,{x:[1,2,3,4],y:[0,-1,-2,-3]}))

>>(0-0)^2+(0.3--1)^2+(0.6--2)^2+(0.9--3)^2=23.66

最后,输出会变成0.我们猜测他是在运行过程中为W和b找到了最好的值,使其与之比配。

8.tf.train API(optimizer的使用)
TensorFlow提供了optimizer,他缓慢地更改每个变量,以便最小化损失函数。 最简单的optimizer是梯度下降。 它根据相对于该变量的损失导数的大小修改每个变量。TensorFlow可以使用函数tf.gradients自动生成仅给出模型描述的导数。 为了简单起见,optimizer通常为您做这个。 例如,
  optimizer = tf.train.GradientDescentOptimizer(0.01)
  train = optimizer.minimize(loss)

  sess.run(init) #reset values to incorrect defaults
  for i in range(1000):
        sess.run(train,{x:[1,2,3,4],y:[0,-1,-2,-3]})
  print(sess.run([W,b]))

>>[array([-0.9999969], dtype=float32), array([ 0.99999082],dtype=float32)]


 8.1 .完整的程序
import numpy as np
import tensorflow as tf

# Model parameters
W = tf.Variable([.3], dtype=tf.float32)
b = tf.Variable([-.3], dtype=tf.float32)
# Model input and output
x = tf.placeholder(tf.float32)
linear_model = W * x + b
y = tf.placeholder(tf.float32)
# loss
loss = tf.reduce_sum(tf.square(linear_model - y)) # sum of the squares
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
# training data
x_train = [1,2,3,4]
y_train = [0,-1,-2,-3]
# training loop
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init) # reset values to wrong
for i in range(1000):
  sess.run(train, {x:x_train, y:y_train})

# evaluate training accuracy
curr_W, curr_b, curr_loss = sess.run([W, b, loss], {x:x_train, y:y_train})
print("W: %s b: %s loss: %s"%(curr_W, curr_b, curr_loss)) 

>>W: [-0.9999969] b: [ 0.99999082] loss: 5.69997e-11

可以看出,loss是一个接近于0非常小的值,重复的运行也许会得到不同的loss,因为每次的随机初始化是不同的值
(Ques:为什么是随机初始化的?不是直接初始化为w为0.3和b为-0.3吗)

9 tf.contrib.learn
  tf.contib.learn是一个tensorflow高层学习库,它被用来简化机器学习 ,包括下面几部分:
     9.1 running training loops
     9.2 running evaluation loops
     9.3 managing data sets
     9.4 managing feeding
tf.contrib.learn定义了许多公共的模型

基础使用:(暂时没看)
import tensorflow as tf
# NumPy is often used to load, manipulate and preprocess data.
import numpy as np

# Declare list of features. We only have one real-valued feature. There are many
# other types of columns that are more complicated and useful.
features = [tf.contrib.layers.real_valued_column("x", dimension=1)]

# An estimator is the front end to invoke training (fitting) and evaluation
# (inference). There are many predefined types like linear regression,
# logistic regression, linear classification, logistic classification, and
# many neural network classifiers and regressors. The following code
# provides an estimator that does linear regression.
estimator = tf.contrib.learn.LinearRegressor(feature_columns=features)

# TensorFlow provides many helper methods to read and set up data sets.
# Here we use two data sets: one for training and one for evaluation
# We have to tell the function how many batches
# of data (num_epochs) we want and how big each batch should be.
x_train = np.array([1., 2., 3., 4.])
y_train = np.array([0., -1., -2., -3.])
x_eval = np.array([2., 5., 8., 1.])
y_eval = np.array([-1.01, -4.1, -7, 0.])
input_fn = tf.contrib.learn.io.numpy_input_fn({"x":x_train}, y_train,
                                              batch_size=4,
                                              num_epochs=1000)
eval_input_fn = tf.contrib.learn.io.numpy_input_fn(
    {"x":x_eval}, y_eval, batch_size=4, num_epochs=1000)

# We can invoke 1000 training steps by invoking the  method and passing the
# training data set.
estimator.fit(input_fn=input_fn, steps=1000)

# Here we evaluate how well our model did.
train_loss = estimator.evaluate(input_fn=input_fn)
eval_loss = estimator.evaluate(input_fn=eval_input_fn)
print("train loss: %r"% train_loss)
print("eval loss: %r"% eval_loss)


 

2017年6月13日星期二

KNN实战

写在开头,以下是我在过程中遇到的一些问题
1.关于KNN算法代码里的一些问题
 1.1关于numpy的sum用法

Check out the documentation for numpy.sum, paying particular attention to the axis parameter. 
To sum over columns:
>>> import numpy as np
>>> a = np.arange(12).reshape(4,3)
>>> a.sum(axis=0)
array([18, 22, 26])
Or, to sum over rows:
>>> a.sum(axis=1)
array([ 3, 12, 21, 30])
 
 
 1.2关于numpy的tile
>>> b=tile(a,(2,1))
>>> b
array([[0, 1, 2],
       [0, 1, 2]]) 
 

 1.3关于numpy的argsort
One dimensional array:
>>> x = np.array([3, 1, 2])
>>> np.argsort(x)
array([1, 2, 0]) 
 
 2.1 关于matplotlib中figure问题
   MATLAB, and pyplot, have the concept of the current figure and the current axes. 
All plotting commands apply to the current axes.
The figure() command here is optional because figure(1) will be created by default,
just as a subplot(111) will be created by default if you don’t manually specify 
any axes. The subplot() command specifies numrows, numcols, fignum where fignum 
ranges from 1 to numrows*numcols. 
 


2.KNN算法代码
def classify0(inX,dataSet,labels,k):
 #calculate the distance
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inx,(dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()
    classCount = {}
    #choose the nearest point
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    #range at a list
    sortedClassCount = sorted(classCount.iteritems()),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]
 
3.从文件中读取数据的代码(这种处理文件的流程在很多代码处理文件时都会用到)
def file2matrix(filename):
    fr = open(filename)
    arrayOfLines = fr.readlines()
    numberOfLines = len(arrayOfLines)
    returnMat = zeros(numberOfLines,3)
    classLabelVector = []
    index = 0
    for line in arrayOfLines:
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector 
 
 4.完整的代码 
from numpy import *
import matplotlib
import matplotlib.pyplot as plt
import operator

def createDataSet():
 group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
 labels = ['A','A','B','B']
 return group,labels

def classify0(inX,dataSet,labels,k):
 #calculate the distance
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX,(dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()
    classCount = {}
    #choose the nearest point
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    #range at a list
    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    print(sortedClassCount[0][0])
    return sortedClassCount[0][0]

def file2matrix(filename):
    fr = open(filename)
    arrayOfLines = fr.readlines()
    numberOfLines = len(arrayOfLines)
    returnMat = zeros((numberOfLines,3))
    classLabelVector = []
    index = 0
    for line in arrayOfLines:
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector

#Matplotlib
def draw_point(datingDataMat,datingLabels):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15*array(datingLabels),15*array(datingLabels))
    plt.show()

#due to difference value belongs to difference varies
#we norm the future for more precise outcome
def autoNorm(dataSet):
    minVals = dataSet.min(0) #0 represent gain the min in the column
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals,(m,1))
    normDataSet = normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minVals

#Entry function(It is the function i used in test processor)
def run_knn():
    print("This is the entry function of all")
    datingDataMat,datingLabels = file2matrix("datingTestSet2.txt")
    datingDataMat,ranges,minVals = norm(datingDataMat)
    flag = 0
    true_outcome = 0
    for item in datingDataMat:
        true_labels=classify0(item,datingDataMat,datingLabels,3)
        if true_labels == datingLabels[flag]:
            true_outcome += 1
        print("The true label is %d",true_labels)
        print("The expect label is %d",datingLabels[flag])
        flag += 1
        
    print("The true outcome is:%d",true_outcome)
    print("The total number is:%d",flag)
    print("The right rate is:%f",1.0*true_outcome/flag)
    draw_point(datingDataMat,datingLabels)

#Test function 
def datingClassTest():
    hoRatio = 0.10
    datingDataMat,datingLabels = file2matrix("datingTestSet2.txt")
    normMat,ranges,minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],\
                        datingLabels[numTestVecs:m],3)
        print "the classifier came back with: %d,the real answer is :%d"\
                %(classifierResult,datingLabels[i])
        if (classifierResult != datingLabels[i]): errorCount += 1.0
    print "the total error rate is :%f" %(errorCount/float(numTestVecs))

leetcode 17

17.   Letter Combinations of a Phone Number Medium Given a string containing digits from   2-9   inclusive, return all possible l...