Tensorflow2.0基础

# coding: utf-8

"""张量的基本运算"""

# In[9]:

A = tf.constant([[1., 2.], [3., 4.]])
B = tf.constant([[5., 6.], [7., 8.]])

# output:

(<tf.Tensor: id=31, shape=(2, 2), dtype=float32, numpy=
 array([[1., 2.],
        [3., 4.]], dtype=float32)>,
 <tf.Tensor: id=32, shape=(2, 2), dtype=float32, numpy=
 array([[5., 6.],
        [7., 8.]], dtype=float32)>)


# In[11]:

C = tf.add(A, B) 

# output:

<tf.Tensor: id=33, shape=(2, 2), dtype=float32, numpy=
array([[ 6.,  8.],
       [10., 12.]], dtype=float32)>

# In[13]:

D = tf.matmul(A,B)

# output:

<tf.Tensor: id=34, shape=(2, 2), dtype=float32, numpy=
array([[19., 22.],
       [43., 50.]], dtype=float32)>


""" 自动求导机制 """

# In[8]:

import tensorflow as tf

x = tf.Variable(initial_value=3.)   #用变量的好处是默认打开梯度追踪
with tf.GradientTape() as tape:     # 在 tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导。————记录器
    y = tf.square(x)
y_grad = tape.gradient(y, x)        # 计算y关于x的导数——求导方法
print([y, y_grad])

# output:
[<tf.Tensor: id=26, shape=(), dtype=float32, numpy=9.0>, <tf.Tensor: id=30, shape=(), dtype=float32, numpy=6.0>]


# In[6]:

import tensorflow as tf
X = tf.constant([[1.,2.],[3.,4.]])
y = tf.constant([[1.],[2.]])
w = tf.Variable(initial_value = [[1.],[2.]])   #变量的初始化器:initial_value
b = tf.Variable(initial_value = 1.)
with tf.GradientTape() as tape:
    L = tf.reduce_sum(tf.square(tf.matmul(X,w) + b - y)) 
    #tf.reduce_sum可以通过设置axis来对不同维度求和;tf.reduce_sum(X,0)  = = [4,6] ;tf.reduce_sum(X,1) = = [3,7];tf.reduce_sum(X) = = 10
    #tf.square对tensor里的每一个元素平方,但是不改变tensor的shape
w_grad,b_grad = tape.gradient(L,[w,b])
print([L.numpy(),w_grad.numpy(),b_grad.numpy()])#tensor.numpy()取tensor的值,忽略类型信息
print([L,w_grad,b_grad])


"""线性回归示例"""

X,y

# ### 梯度下降法
# #### 首先构建损失函数
# #### 其次求参数梯度,更新参数
# #### 迭代下一轮

# L = sum_{i=1}^n(ax_i + b - y_i)^2 


# In[45]:

import numpy as np

X_raw = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32)
y_raw = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)

X = (X_raw - X_raw.min()) / (X_raw.max() - X_raw.min())   #归一化
y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())




""" 一、NumPy 下的线性回归 """

# In[14]:

a,b = 0, 0
num_epoch = 10000
lr = 1e-3
for e in range(num_epoch):
    y_pred = a*X + b
    grad_a,grad_b = (y_pred - y).dot(X),(y_pred - y).sum()
    a,b  =  a - lr*grad_a, b-lr*grad_b
print(a,b)

# output:
0.9763702027872221 0.057564988311377796

# #### 再深再复杂的模型就很痛苦了

""" 二、TensorFlow 下的线性回归"""

# ### 默认开启Eager Execution(动态图)模式 

# In[47]:

X= tf.constant(X)        #tensor化
y = tf.constant(y)

a = tf.Variable(initial_value = 0.)          #参数初始化
b = tf.Variable(initial_value = 0.)

variables = [a,b]

num_epoch = 10000
optimizer = tf.keras.optimizers.SGD(learning_rate = 1e-3)   #声明优化器
for e in range(num_epoch):
    with tf.GradientTape() as tape:  #对正向传播和损失函数,开启梯度记录器
        y_pred = a*X+b
        loss = 0.5*tf.reduce_sum(tf.square(y_pred - y))
    grads = tape.gradient(loss,variables)          #计算梯度
    optimizer.apply_gradients(grads_and_vars = zip(grads,varibales))      
        #更新参数关键字:grads_and_vars: 需要传入一个python列表,[(grad_a, a), (grad_b, b)] 。
        #因此用python内置函数zip(g,v) 将参数和梯度打包拼装成需要的参数形式
        #梯度归0
print(a,b)
        
# output:
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0> <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>



""" python内置函数zip"""

# In[42]:
a = [1, 3, 5]
b = [2, 4, 6]
zip(a,b) 
  
# output:
 [(1,2),(3,4),(5,6) ]

"""
整个流程总结:
    """
    构建模型 tf.keras.Model 和tf.keras.layers
    模型损失:tf.keras.losses
    模型优化器:tf.keras.optimizer
    模型评估:tf.keras.metrics
    """

import tensorflow as tf
import numpy as np
class MyModel(tf.keras.Model):
    def __init__(self):
        super().__init__()     # Python 2 下使用 super(MyModel, self).__init__()
        # 此处添加初始化代码(包含 call 方法中会用到的层),例如
        # layer1 = tf.keras.layers.BuiltInLayer(...)
        # layer2 = MyCustomLayer(...)

    def call(self, input):                                        #实现的是模型的调用 y_pred = Model(X)的过程
        #此处添加模型调用的代码(处理输入并返回输出),例如
         x = layer1(input)
         output = layer2(x)
        return output

    # 还可以添加自定义的方法
"""
layers对变量和计算流程进行封装(如全连接层dense,卷积层,池化层),Model对各种layers进行组织链接,并封装成一个整体,Model描述的是由输入到输出的运算过程。
模型定义通过继承父类tf.keras.Model实现,还要重写init() (构造函数,初始化)和 call(input) (模型调用,重写)两个方法,同时也可以根据需要增加自定义的方法。
构造函数初始化模型所需的所有层,call()方法描述了输入如何由输入数据得通过layers得到输出
"""

"""
kernel_initializer 、 bias_initializer :权重矩阵 kernel 和偏置向量 bias 两个变量的初始化器。默认为 tf.glorot_uniform_initializer 1 。设置为 tf.zeros_initializer 表示将两个变量均初始化为全 0
"""



模型继承:
class Linear(tf.keras.Model):

模型实例化
model = Linear() #相当于Linear.call()

"""
模型为何非要继承并重写父类tf.keras.Model实现?? 因为父类实现了很多包括其他的属性,如在实例化模型后,可以用model.variable直接获得模型所有变量等,因此要继承。

#相当于Linear.call() 私有属性 父类tf.keras.Model其实定义了call()方法来,为何不直接重写call()来调用Linear() y_pred = Linear(X).而是又实现一个call()方法暴露出来来重写呢? 这是因为后期 Keras 在模型调用的前后还需要有一些自己的内部操作,所以暴露出一个专门用于重载的 call() 方法,然后我们去重写
"""

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值