学习笔记-深度学习-Keras和TensorFlow初步了解

内容是对《Python深度学习》的摘录、理解、代码实践和遇到的问题。

TensorFlow:是一个基于Python的免费开源机器学习平台,拥有庞大的组件生态系统。包含很多底层张量计算API。

Keras:构建于TensorFlow之上的,Python编写的高阶深度学习API

通过TensorFlow,Keras可以在不同类型的硬件上运行,还可以扩展到数千台机器上。

训练神经网络主要围绕以下概念进行:

一、通过TensorFlow API实现的低阶张量操作

  1. 张量
  2. 张量运算
  3. 反向传播

二、通过Keras API实现的高阶深度学习概念

  1. 损失函数
  2. 优化器
  3. 指标:用于评估模型性能,例如精度
  4. 训练循环

常数张量

创建全1或全0张量:

import tensorflow as tf
x = tf.ones(shape=(2, 1))
print(x)

tf.Tensor(

[[1.]

 [1.]], shape=(2, 1), dtype=float32)

x = tf.zeros(shape=(2, 1))

print(x)

tf.Tensor(

[[0.]

 [0.]], shape=(2, 1), dtype=float32)

从随机分布中取值来创建张量

import tensorflow as tf

x = tf.random.normal(shape=(3, 1), mean=0., stddev=1.)  # 从均值为0、标准差为1的正态分布中抽取的形状为(3,1)的随机张量

print(x)

tf.Tensor(

[[ 2.4061456 ]

 [ 0.4366203 ]

 [-0.14396065]], shape=(3, 1), dtype=float32)

import tensorflow as tf

x = tf.random.uniform(shape=(3, 1), minval=0., maxval=1.)   # 从0和1之间的均匀分布中抽取的随机张量

print(x)

tf.Tensor(

[[0.6344434 ]

 [0.48669887]

 [0.44374537]], shape=(3, 1), dtype=float32)

注意TensorFlow张量是不可赋值的,以下代码会报错

x = tf.ones(shape=(3, 1))

x[0, 0] = 0.

如果需要更新状态,则应该使用变量。

变量

创建TensorFlow变量

import tensorflow as tf

v = tf.Variable(initial_value=tf.random.normal(shape=(3, 1), mean=0., stddev=1.))

print(v)

<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=

array([[-0.10057034],

       [-0.94686824],

       [ 1.5012082 ]], dtype=float32)>

变量用常数张量进行初始赋值。

修改TensorFlow变量

变量的状态可以通过assign方法修改

v.assign(tf.ones(shape=(3, 1)))

print(v)

<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=

array([[1.],

       [1.],

       [1.]], dtype=float32)>

这种方法也适用于变量的子集

v[0, 0].assign(3.)

print(v)

<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=

array([[3.],

       [1.],

       [1.]], dtype=float32)>

assign_add()assign_sub()分别等同于+=和-=

v.assign_add(tf.ones(shape=(3, 1)))

print(v)

<tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=

array([[4.],

       [2.],

       [2.]], dtype=float32)>

张量运算

a = tf.ones(shape=(2, 2))

b = tf.square(a)    # 求平方

c = tf.sqrt(a)  # 求平方根

d = b + c   # 两个张量逐元素相加

e = tf.matmul(a, b)  # 计算两个张量的点积

f = e * d   # 计算两个张量逐元素相乘(叉积)

GradientTape API

TensorFlow可以检索任意可微表达式相对于其输入的梯度,只需要创建一个GradientTape作用域,对一个或多个输入张量做一些计算后,可以检索计算结果相对于输入的梯度。

import tensorflow as tf

input_var = tf.Variable(initial_value=3.)

with tf.GradientTape() as tape:

    result = tf.square(input_var)

    gradient = tape.gradient(result, input_var)

print(gradient)

tf.Tensor(6.0, shape=(), dtype=float32)

利用嵌套的梯度带还能计算二阶梯度(梯度的梯度)

import tensorflow as tf

time = tf.Variable(0.)

with tf.GradientTape() as outer_tape:

    with tf.GradientTape() as inner_tape:

        position = 4.9 * time ** 2

        speed = inner_tape.gradient(position, time)

    accelerate = outer_tape.gradient(speed, time)

print(accelerate)

tf.Tensor(9.8, shape=(), dtype=float32)

用TensorFlow实现线性分类器

在二维平面上随机生成两个类别的点

生成两个点云,设定两个点云的协方差矩阵相同但均值不同,也即两个点云具有相同的形状但位置不同。

import tensorflow as tf

import matplotlib.pyplot as plt



num_samples_per_class = 1000

# 生成第一个类别的点云

negative_samples = tf.random.normal(shape=(num_samples_per_class, 2), mean=-3., stddev=1)

# 生成第二个类别的点云

positive_samples = tf.random.normal(shape=(num_samples_per_class, 2), mean=4., stddev=1)

# 将二者堆叠,形成一个形状为(2000,2)的数组

# tf.concat([tensor1, tensor2, ...], axis)第一个参数表示需要拼接的张量是哪些,第二个参数表示在哪个轴上拼接

inputs = tf.concat([negative_samples, positive_samples], 0)

# 生成对应的目标标签,以0标识negative_samples,以1标识positive_samples,根据上面的堆叠,前1000个标签应为0,后1000个应为1

targets = tf.concat([tf.zeros(shape=(num_samples_per_class,)), tf.ones(shape=(num_samples_per_class,))], 0)



# 绘制两个点类的图像

plt.scatter(inputs[:, 0], inputs[:, 1], c=targets[:])

plt.show()

 

实现线性分类器

采用仿射变换(prediction = W·input + b)来创建分类器

# 创建线性分类器的变量

input_dim = 2   # 输入样本是二维点坐标

output_dim = 1  # 每个样本输出一个预测值,如果预测该点接近分类0则值会更接近0,反之更接近1

W = tf.Variable(initial_value=tf.random.uniform(shape=(input_dim, output_dim)))

b = tf.Variable(initial_value=tf.zeros(shape=(output_dim, )))





#   向前传播函数

def model(inputs_):

    return tf.matmul(inputs_, W) + b





#   均方误差损失函数

def square_loss(targets_, predictions_):

    per_sample_losses = tf.square(targets_ - predictions_)  # 该变量与targets_、predictions_形状相同,其中包含每个样本的损失值

    return tf.reduce_mean(per_sample_losses)    # 取所有样本损失值的平均值,通过reduce_mean()实现





#   训练步骤函数

learning_rate = 0.02

def training_step(inputs_, targets_):

    # 以下三行是在一个梯度带内进行了一次向前传播

    with tf.GradientTape() as tape:

        predictions_ = model(inputs_)

        loss_ = square_loss(targets_, predictions_)

    grad_loss_wrt_W, grad_loss_wrt_b = tape.gradient(loss_, [W, b])  # 检索损失loss相对于权重W、b的梯度

    # 更新权重

    W.assign_sub(learning_rate * grad_loss_wrt_W)

    b.assign_sub(learning_rate * grad_loss_wrt_b)

    return loss_





#   为简单起见,不进行分批,直接在所有数据上进行批量训练,运行时间要更长,但每次更新都包含所有的样本信息所以所需迭代次数更少

for step in range(40):  # 迭代40次

    loss = training_step(inputs, targets)

    print(f"Loss at step {step}: {loss:.4f}")





#   以0.5为分界线划分两类,绘制处模型预测情况

predictions = model(inputs)

plt.scatter(inputs[:, 0], inputs[:, 1], c=predictions[:] > 0.5)

plt.show()

遇到的问题

每一步应该都理解了,但是损失小时模型预测出的图像和原图像完全不像,损失大时模型预测出的图像反而比较吻合

learning_rate = 0.1

learning_rate = 0.02

不过从上图能看出线性分类器的作用:找到一条直线(或高维空间中的一个超平面)的参数,将两类数据整齐地分开.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。对于您的问题,我理解您想问我如何调用U-NET模型,以下是我给出的回答。 首先,U-NET模型是一个用于图像分割的深度学习模型,它使用卷积神经网络来学习图像中不同区域的特征,并将它们分割成不同的类别。在TensorFlow 2.0中,我们可以使用tf.keras API来实现U-NET模型。 以下是一个简单的U-NET模型的实现代码: ```python import tensorflow as tf from tensorflow.keras.layers import * def conv_block(inputs, filters, kernel_size=(3, 3), activation='relu', padding='same'): x = Conv2D(filters, kernel_size, activation=activation, padding=padding)(inputs) x = BatchNormalization()(x) x = Conv2D(filters, kernel_size, activation=activation, padding=padding)(x) x = BatchNormalization()(x) return x def unet(input_shape=(256, 256, 3)): inputs = Input(shape=input_shape) c1 = conv_block(inputs, 64) p1 = MaxPooling2D((2, 2))(c1) c2 = conv_block(p1, 128) p2 = MaxPooling2D((2, 2))(c2) c3 = conv_block(p2, 256) p3 = MaxPooling2D((2, 2))(c3) c4 = conv_block(p3, 512) p4 = MaxPooling2D((2, 2))(c4) c5 = conv_block(p4, 1024) u6 = Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(c5) u6 = concatenate([u6, c4]) c6 = conv_block(u6, 512) u7 = Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(c6) u7 = concatenate([u7, c3]) c7 = conv_block(u7, 256) u8 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(c7) u8 = concatenate([u8, c2]) c8 = conv_block(u8, 128) u9 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(c8) u9 = concatenate([u9, c1]) c9 = conv_block(u9, 64) outputs = Conv2D(1, (1, 1), activation='sigmoid')(c9) model = tf.keras.Model(inputs=[inputs], outputs=[outputs]) return model ``` 在这个实现中,我们使用了Conv2D、BatchNormalization、MaxPooling2D和Conv2DTranspose等层来构建U-NET模型。我们还定义了一个conv_block函数来简化代码。 使用这个实现代码,我们可以通过以下方式调用U-NET模型: ```python model = unet() ``` 这将返回一个U-NET模型的实例,我们可以使用该实例来进行训练和预测。 希望这个回答对您有所帮助。如果您还有其他问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值