x.ndim #查看张量的形状
x.dtype #查看张量的属性
3d张量:三维数组
3d向量:向量中有三个元素
深度学习中所有数据张量的第一个轴(0轴)都是样本轴,存放着样本名(个人理解)
为复杂,高度折叠的数据流找到简洁的表示。
与人类展开纸球的策略大致相同。
每个神经层都用下述方法对输入数据进行变换:
o u t p u t = r e l u ( d o t ( w , i n p u t ) + b ) output=relu(dot(w,input)+b) output=relu(dot(w,input)+b)
w和b都是张量,为改成的属性。被称为层的权重(可训练参数)。
更新权重的方法:梯度(张量运算的导数,是多元函数导数的推广。)
常用:小批量随机梯度下降(SGD),其他的变体被称为优化器。
损失函数:在训练过程中需要将其最小化。他能衡量当前任务是否已经完成。
网络输出是一个概率值,最好使用binary_crossentropy(二元交叉熵),也可以使用mean_squared_error(均方误差)。
优化器:决定如何基于损失函数对网络进行更新。她执行的是随机梯度下降(SGD)的某个变体。
优化器和损失函数均可以自定义。
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data() #导入数据
数据结构的核心组建是层,通过几个层来实现数据的筛选。
Dense层:全连接层
activation:激活函数,为了让训练过程变得非线性。
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
layers.Dense(512, activation="relu"), #本层为dense全连接层,拥有512个隐藏的神经元,激活函数为relu,
layers.Dense(10, activation="softmax") #本层为dense全连接层,拥有10个输出单元,会返回一个由10个概率值(总和为1)组成的数组,每个概率值表示当前数字图像属于10个数字类别中某一个的概率。
])
优化器(optimizer)
损失函数(loss)
需要监控的指标(metric)
model.compile(optimizer="有人说,看懂了大话西游,你就明白了爱情是什么,明白了又怎样,放不开的还是放不开",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
#对训练集做处理
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255 #将数据归一化,会使模型训练得更好
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255
#对标签进行处理
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
训练批次:epochs
数据批量:batch_size
model.fit(train_images,train_labels,epochs=5,batch_size=128)
IMDB数据集:50 000条两极分化的电影评论。
train_data是由每个评论组成,每条评论是由单词索引组成的列表
from tensorflow.keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)#选取前10000个最常出现的单词,便于处理
word_index = imdb.get_word_index() #加载IMDB内置的单词字典
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()]) #构建解码字典
decoded_review = " ".join([reverse_word_index.get(i - 3, "?") for i in train_data[0]]) #进行解码,i-3是因为0,1,2是为(填充,序列的开始,未知词)分别保留的序列
(数据向量化)
#将数据编码独热化
import numpy as np
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
for j in sequence:
results[i, j] = 1.
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
#将标签向量化
y_train = np.asarray(train_labels).astype("float32")
y_test = np.asarray(test_labels).astype("float32")
对dense层的堆叠,需要确定以下两个关键架构
激活函数:
relu函数可以将所有负值归0
sigmoid函数可以将任意值‘压缩’到[0,1]区间内,其输出值可以看作概率值。
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential()
model.add(layers.Dense(16, activation="relu"))
model.add(layers.Dense(16, activation="relu"))
model.add(layers.Dense(1, activation="rsigmoid"))
model.compile(optimizer="rmsprop",
loss="binary_crossentropy",
metrics=["accuracy"])
#1.留出验证集
x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]
#2.训练模型
history = model.fit(partial_x_train,
partial_y_train,
epochs=20,
batch_size=512,
validation_data=(x_val, y_val))
#3.结果的查看
#调用model.fit()会返回一个history对象,这对象有个history字典
history_dict = history.history
history_dict.keys()
#4.绘制训练损失和验证损失
import matplotlib.pyplot as plt
history_dict = history.history
loss_values = history_dict["loss"]
val_loss_values = history_dict["val_loss"]
epochs = range(1, len(loss_values) + 1)
plt.plot(epochs, loss_values, "bo", label="Training loss")
plt.plot(epochs, val_loss_values, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.show()
#5.绘制训练精度和验证精度
import matplotlib.pyplot as plt
acc = history_dict["accuracy"]
val_acc = history_dict["val_accuracy"]
plt.plot(epochs, acc, "bo", label="Training acc")
plt.plot(epochs, val_acc, "b", label="Validation acc")
plt.title("Training and validation accuracy")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()
plt.show()
model.predict(x_test)
路透社数据集包含46个新闻主题,每个主题至少有10个样本。
from tensorflow.keras.datasets import reuters
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)
#数据集解码
word_index = reuters.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_newswire = " ".join([reverse_word_index.get(i - 3, "?") for i in
train_data[0]])
#将数据向量化
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
#将标签向量化
#方法1
def to_one_hot(labels, dimension=46):
results = np.zeros((len(labels), dimension))
for i, label in enumerate(labels):
results[i, label] = 1.
return results
y_train = to_one_hot(train_labels)
y_test = to_one_hot(test_labels)
#方法2
from tensorflow.keras.utils import to_categorical
y_train = to_categorical(train_labels)
y_test = to_categorical(test_labels)
如果要对n个类别进行分类,网络的最后一层应该是大小为n的dense层。
网络的最后一层是大小为46的dense层,前面的层不应该比他更小,因为这样会使部分信息永久丢失。
model = keras.Sequential([
layers.Dense(64, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(46, activation="softmax")
])
softmax函数:可以输出不同输出类别上的概率分布,每个类别累加起来的概率综合为1
对于多分类问题,最好的损失函数就是categorical_crossentropy(分类交叉熵)。可以衡量两个概率分布之间的距离,这里的两个概率分布分别是网络输出的概率分布和标签的真是分布。通过使两个分布距离达到最小化,使输出结果尽可能接近真是标签。
model.compile(optimizer="rmsprop",
loss="categorical_crossentropy",
metrics=["accuracy"])
#留出验证集
x_val = x_train[:1000]
partial_x_train = x_train[1000:]
y_val = y_train[:1000]
partial_y_train = y_train[1000:]
#训练模型
history = model.fit(partial_x_train,
partial_y_train,
epochs=20,
batch_size=512,
validation_data=(x_val, y_val))
predictions = model.predict(x_test)
predictions[0].shape #每个元素长度都是46
np.sum(predictions[0]) #所有元素总和为1
np.argmax(predictions[0]) #最大的元素就是预测类别,就是概率最大的类别
将其转换为整数张量,1-46。
需要改变的是损失函数的选择,需要选择sparse_categorical_crossentropy
from tensorflow.keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
#数据标准化
mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std
test_data -= mean
test_data /= std
由于样本数量很少,我们只使用一个非常小的网络。
一般来说,训练数据越少,过拟合会越严重,我们用较小的网络可以降低过拟合。
网络的最后一层只有一个单元,没有激活,是一个线性层,这就是标量回归的典型设置。
损失函数为MSE均方误差,是回归问题常用的损失函数。
#因为后续操作需要多次用到这个模型,所以用一个函数来构造
def build_model():
model = keras.Sequential([
layers.Dense(64, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(1)
])
model.compile(optimizer="rmsprop", loss="mse", metrics=["mae"])
return model
这里利用了一个新的方法:k折验证法。将数据分为k个区,每组数据分别成为验证集,之后将k次训练集的分数平均起来得到模型的最终分数。
k = 4
num_val_samples = len(train_data) // k
num_epochs = 100
all_scores = []
for i in range(k):
print(f"Processing fold #{i}")
#准备验证数据
val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples]
val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]
#准备训练数据
partial_train_data = np.concatenate(
[train_data[:i * num_val_samples],
train_data[(i + 1) * num_val_samples:]],
axis=0)
partial_train_targets = np.concatenate(
[train_targets[:i * num_val_samples],
train_targets[(i + 1) * num_val_samples:]],
axis=0)
#构建已编译的keras模型
model = build_model()
model.fit(partial_train_data, partial_train_targets,
epochs=num_epochs, batch_size=16, verbose=0) #verbose=0,静默模式
#在验证集上评估模型
val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0)
all_scores.append(val_mae)
#最终的分数
np.mean(all_scores)
关于模型的验证:
二分类问题:
多分类问题:
回归问题: