时间序列预测与风格迁移:从数据预测到图像风格转换
1. 时间序列预测
1.1 数据准备
首先,我们需要对数据进行处理,将其转换为适合模型训练的格式。以下是具体的代码实现:
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
import sklearn.preprocessing
import seaborn as sns
url = 'https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch11/london_merged.csv'
df = pd.read_csv(url, parse_dates=['timestamp'], index_col="timestamp")
# 检查平稳性
from statsmodels.tsa.vector_ar.vecm import coint_johansen
johan_test_temp = df
coint_johansen(johan_test_temp, -1, 1).eig
# 绘制数据
plt.figure(figsize = (16,4))
plt.plot(df.index, df["cnt"]);
# 创建索引
df['hour'] = df.index.hour
df['month'] = df.index.month
# 绘制不同特征与目标值的关系图
fig, (ax1, ax2, ax3) = plt.subplots(nrows = 3)
fig.set_size_inches(16, 10)
sns.pointplot(data = df, x = 'month', y = 'cnt', hue = 'is_weekend', ax = ax1)
sns.pointplot(data = df, x = 'hour', y = 'cnt', hue = 'season', ax = ax2);
sns.pointplot(data = df, x = 'month', y = 'cnt', ax = ax3)
# 缩放数值列
scaler = sklearn.preprocessing.MinMaxScaler()
df['t1'] = scaler.fit_transform(df['t1'].values.reshape(-1,1))
df['t2'] = scaler.fit_transform(df['t2'].values.reshape(-1,1))
df['hum'] = scaler.fit_transform(df['hum'].values.reshape(-1,1))
df['wind_speed'] = scaler.fit_transform(df['wind_speed'].values.reshape(-1,1))
df['cnt'] = scaler.fit_transform(df['cnt'].values.reshape(-1,1))
# 划分训练集和测试集
train_size = int(len(df) * 0.9)
test_size = len(df) - train_size
train, test = df.iloc[0:train_size], df.iloc[train_size:len(df)]
# 创建数据集
def create_dataset(X, y, time_steps = 1):
Xs, ys = [], []
for i in range(len(X) - time_steps):
v = X.iloc[i:(i + time_steps)].values
Xs.append(v)
ys.append(y.iloc[i + time_steps])
return np.array(Xs), np.array(ys)
time_steps = 10
X_train, y_train = create_dataset(train, train.cnt, time_steps)
X_test, y_test = create_dataset(test, test.cnt, time_steps)
batch_size = 256
buffer_size = 1000
train_data = tf.data.Dataset.from_tensor_slices((X_train , y_train))
train_data = train_data.cache().shuffle(buffer_size).batch(batch_size).repeat()
test_data = tf.data.Dataset.from_tensor_slices((X_test , y_test))
test_data = test_data.batch(batch_size).repeat()
1.2 模型创建
接下来,我们定义一个简单的 LSTM 模型:
simple_lstm_model = tf.keras.models.Sequential([
tf.keras.layers.LSTM(8, input_shape = X_train.shape[-2:]),
tf.keras.layers.Dense(1)
])
simple_lstm_model.compile(optimizer = 'adam', loss = 'mae')
1.3 模型训练
使用
fit
方法对模型进行训练:
EVALUATION_INTERVAL = 200
EPOCHS = 10
history = simple_lstm_model.fit(
train_data,
epochs = EPOCHS,
steps_per_epoch = EVALUATION_INTERVAL,
validation_data = test_data,
validation_steps = 50)
1.4 损失可视化
训练完成后,我们可以绘制训练损失和验证损失的曲线:
plt.plot(history.history['loss'], label = 'train loss')
plt.plot(history.history['val_loss'], label = 'validation loss')
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.show()
从损失曲线中,我们可以观察到模型是否存在过拟合等问题。如果损失在训练集和验证集上都趋于稳定,且两者之间的差距较小,说明模型训练效果较好。
1.5 模型评估
使用
predict
方法对测试数据进行预测,并绘制预测结果与实际值的对比图:
X_test, y_test = create_dataset(df, df.cnt, 10)
y_pred = simple_lstm_model.predict(X_test)
def create_time_steps(length):
return list(range(-length, 0))
plt.figure(figsize = (16,4))
num_in = create_time_steps(91)
num_out = 28
plt.plot(num_in, y_train[15571:], label = 'history')
plt.plot(np.arange(num_out), y_test[15661:15689], 'b', label='Actual ')
plt.plot(np.arange(num_out), y_pred[15661:15689], 'r', label = 'Predicted')
plt.xlabel("Time")
plt.ylabel("bike shares (Normalized Value)")
plt.legend()
plt.show()
1.6 未来数据点预测
预测下一个自行车共享数量:
y_pred = simple_lstm_model.predict(X_test[-1:])
print(y_pred)
plt.figure(figsize = (16,4))
num_in = create_time_steps(100)
num_out = 1
plt.plot(num_in, y_test[-100:])
plt.plot(np.arange(num_out), y_pred, 'ro', label = 'Predicted')
plt.xlabel("Time")
plt.ylabel("bike shares (Normalized Value)")
plt.legend()
plt.show()
1.7 多数据点预测
我们还可以预测未来一段时间内的自行车共享需求:
df2 = df['2017-01-03 14:00:00':'2017-01-03 23:00:00']
df1 = df['2016-01-04 00:00:00':'2016-01-06 23:00:00']
df1['cnt'] = 0
df_future = df2.append(df1, sort = False)
predictions = []
for i in range(50):
X_f, y_f = create_dataset(df_future, df_future.cnt, time_steps)
y_pred = simple_lstm_model.predict(X_f[i:i+1])
df_future['cnt'][i+10] = y_pred
predictions.append(float(y_pred[0][0]))
plt.figure(figsize = (16,4))
num_in = create_time_steps(100)
num_out = 50
plt.plot(num_in, y_test[-100:], label = 'History')
plt.plot(np.arange(num_out), predictions, 'r', label = 'Predicted')
plt.xlabel("Time")
plt.ylabel("bike shares (Normalized Value)")
plt.legend()
plt.show()
1.8 统计模型
除了神经网络模型,还有一些统计模型可用于时间序列分析,例如 VAR 模型:
from statsmodels.tsa.vector_ar.var_model import VAR
model = VAR(endog = train)
result = model.fit()
prediction = result.forecast(validation_data.y, steps = len(valid))
2. 风格迁移
2.1 简介
风格迁移是一种利用神经网络将一幅图像的风格应用到另一幅图像上的技术。通过这种技术,我们可以将自己拍摄的照片转换为著名艺术家的绘画风格。
2.2 快速风格迁移
TF Hub 提供了一个预训练模型 “arbitrary-image-stylization-v1-256/2” 用于快速风格迁移。以下是具体的操作步骤:
1.
创建项目
:
import tensorflow as tf
import re
import urllib
import numpy as np
import matplotlib.pyplot as plt
import PIL.Image
import tensorflow_hub as hub
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from matplotlib import gridspec
from IPython import display
from PIL import Image
- 下载图像 :
def download_image_from_URL(imageURL):
imageName = re.search('[a-z0-9\-]+\.(jpe?g|png|gif|bmp|JPG)', imageURL, re.IGNORECASE)
imageName = imageName.group(0)
urllib.request.urlretrieve(imageURL, imageName)
imagePath = "./" + imageName
return imagePath
target_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/ferns.jpg"
target_path = download_image_from_URL(target_url)
style_url = "https://raw.githubusercontent.com/Apress/artificial-neural-networks-with-tensorflow-2/main/ch12/on-the-road.jpg"
style_path = download_image_from_URL(style_url)
- 显示图像 :
content = Image.open(target_path)
style = Image.open(style_path)
plt.figure(figsize=(10, 10))
plt.subplot(1, 2, 1)
plt.imshow(content)
plt.title('Content Image')
plt.subplot(1, 2, 2)
plt.imshow(style)
plt.title('Style Image')
plt.tight_layout()
plt.show()
- 准备图像输入 :
def image_to_tensor_style(path_to_img):
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
img = tf.image.resize(img, [256,256])
img = img[tf.newaxis, :]
return img
def image_to_tensor_target(path_to_img, image_size):
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)
img = tf.image.resize(img, [image_size,image_size], preserve_aspect_ratio=True)
img = img[tf.newaxis, :]
return img
output_image_size = 400
target_image = image_to_tensor_target(target_path, output_image_size)
style_image = image_to_tensor_style(style_path)
2.3 总结
风格迁移技术为我们提供了一种有趣的方式来处理图像,通过使用预训练模型,我们可以快速实现图像风格的转换。而时间序列预测则帮助我们对未来的数据进行预测,在实际应用中具有重要的价值。
2.4 流程图
graph LR
A[开始] --> B[时间序列预测]
B --> B1[数据准备]
B --> B2[模型创建]
B --> B3[模型训练]
B --> B4[模型评估]
B --> B5[未来数据点预测]
B --> B6[多数据点预测]
B --> B7[统计模型]
A --> C[风格迁移]
C --> C1[简介]
C --> C2[快速风格迁移]
C2 --> C21[创建项目]
C2 --> C22[下载图像]
C2 --> C23[显示图像]
C2 --> C24[准备图像输入]
C --> C3[总结]
2.5 表格
| 技术 | 描述 |
|---|---|
| 时间序列预测 | 利用神经网络或统计模型对未来数据进行预测 |
| 风格迁移 | 利用神经网络将一幅图像的风格应用到另一幅图像上 |
2.6 深入理解风格迁移原理
虽然使用预训练模型可以快速实现风格迁移,但了解其背后的原理能帮助我们更好地进行自定义调整。风格迁移的核心思想是将内容图像的内容信息和风格图像的风格信息进行融合。
在神经网络中,不同层的特征图包含了不同层次的信息。较浅的层通常捕捉到图像的细节信息,如边缘、纹理等,这些信息与图像的风格相关;而较深的层则捕捉到图像的语义信息,如物体的形状、结构等,这些信息与图像的内容相关。
通过计算内容图像和风格图像在不同层的特征图之间的差异,并将这些差异作为损失函数进行优化,我们可以逐步调整内容图像,使其既保留原有的内容信息,又具有风格图像的风格信息。
2.7 自定义风格迁移实现思路
如果我们想要实现自定义的风格迁移,可以按照以下步骤进行:
1.
定义损失函数
:
-
内容损失
:计算内容图像和生成图像在内容层的特征图之间的均方误差。
-
风格损失
:计算风格图像和生成图像在风格层的特征图之间的格拉姆矩阵的均方误差。
-
总损失
:将内容损失和风格损失按照一定的权重进行加权求和。
2.
选择优化器
:使用优化器(如 Adam)来最小化总损失。
3.
迭代优化
:不断更新生成图像的像素值,直到总损失达到一个较小的值。
以下是一个简单的自定义风格迁移的代码示例:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.applications.vgg19 import VGG19, preprocess_input
from tensorflow.keras.preprocessing.image import load_img, img_to_array
# 加载预训练的 VGG19 模型
base_model = VGG19(include_top=False, weights='imagenet')
# 定义内容层和风格层
content_layers = ['block5_conv2']
style_layers = ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1', 'block5_conv1']
# 定义提取特征的模型
content_extractor = tf.keras.Model(inputs=base_model.input, outputs=[base_model.get_layer(name).output for name in content_layers])
style_extractor = tf.keras.Model(inputs=base_model.input, outputs=[base_model.get_layer(name).output for name in style_layers])
# 定义格拉姆矩阵计算函数
def gram_matrix(input_tensor):
result = tf.linalg.einsum('bijc,bijd->bcd', input_tensor, input_tensor)
input_shape = tf.shape(input_tensor)
num_locations = tf.cast(input_shape[1]*input_shape[2], tf.float32)
return result/(num_locations)
# 定义风格损失函数
def style_loss(style, combination):
gram_style = gram_matrix(style)
gram_combination = gram_matrix(combination)
return tf.reduce_mean(tf.square(gram_style - gram_combination))
# 定义内容损失函数
def content_loss(content, combination):
return tf.reduce_mean(tf.square(content - combination))
# 定义总损失函数
def total_loss(content_image, style_image, combination_image, content_weight=1e3, style_weight=1e-2):
content_features = content_extractor(preprocess_input(content_image))
style_features = style_extractor(preprocess_input(style_image))
combination_content_features = content_extractor(preprocess_input(combination_image))
combination_style_features = style_extractor(preprocess_input(combination_image))
c_loss = content_loss(content_features[0], combination_content_features[0])
s_loss = 0
for style_feature, combination_style_feature in zip(style_features, combination_style_features):
s_loss += style_loss(style_feature, combination_style_feature)
s_loss /= len(style_layers)
return content_weight * c_loss + style_weight * s_loss
# 加载内容图像和风格图像
content_image = load_img('content.jpg', target_size=(512, 512))
content_image = img_to_array(content_image)
content_image = np.expand_dims(content_image, axis=0)
style_image = load_img('style.jpg', target_size=(512, 512))
style_image = img_to_array(style_image)
style_image = np.expand_dims(style_image, axis=0)
# 初始化生成图像
combination_image = tf.Variable(content_image, dtype=tf.float32)
# 定义优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=0.02)
# 迭代优化
epochs = 100
for epoch in range(epochs):
with tf.GradientTape() as tape:
loss = total_loss(content_image, style_image, combination_image)
grads = tape.gradient(loss, combination_image)
optimizer.apply_gradients([(grads, combination_image)])
if epoch % 10 == 0:
print(f'Epoch {epoch}, Loss: {loss.numpy()}')
# 显示生成的图像
generated_image = combination_image.numpy()[0].astype(np.uint8)
plt.imshow(generated_image)
plt.title('Generated Image')
plt.show()
2.8 对比不同风格迁移方法
| 方法 | 优点 | 缺点 |
|---|---|---|
| 使用 TF Hub 预训练模型 | 快速简单,无需深入了解原理;可处理任意风格 | 灵活性较低,难以进行自定义调整 |
| 自定义风格迁移 | 可以根据需求进行灵活调整;深入理解风格迁移原理 | 实现复杂度较高,需要更多的计算资源和时间 |
2.9 实际应用场景
- 艺术创作 :艺术家可以利用风格迁移技术将自己的作品转换为不同的艺术风格,拓展创作思路。
- 图像处理 :在图像编辑软件中添加风格迁移功能,让用户可以轻松地为照片添加独特的风格。
- 文化传承 :将古代绘画的风格应用到现代照片上,促进文化的传承和创新。
2.10 未来发展趋势
随着深度学习技术的不断发展,风格迁移技术也将不断进步。未来可能会出现更加高效、灵活的风格迁移算法,能够更好地处理复杂的图像和风格。同时,风格迁移技术也可能会与其他领域(如虚拟现实、增强现实)相结合,创造出更加丰富的应用场景。
2.11 总结与展望
本文介绍了时间序列预测和风格迁移两种技术。时间序列预测通过神经网络或统计模型帮助我们对未来的数据进行预测,在金融、气象、交通等领域具有广泛的应用。风格迁移则利用神经网络将一幅图像的风格应用到另一幅图像上,为艺术创作和图像处理带来了新的可能性。
在实际应用中,我们可以根据具体的需求选择合适的方法。如果追求快速简单的实现,可以使用预训练模型;如果需要进行自定义调整,则可以深入研究并实现自定义的风格迁移算法。
未来,随着技术的不断发展,这两种技术都将不断完善和拓展,为我们的生活和工作带来更多的便利和创新。我们可以期待在更多的领域看到它们的应用,创造出更加美好的未来。
2.12 流程图
graph LR
A[自定义风格迁移] --> B[定义损失函数]
B --> B1[内容损失]
B --> B2[风格损失]
B --> B3[总损失]
A --> C[选择优化器]
A --> D[迭代优化]
D --> E[更新生成图像]
E --> F[判断是否达到终止条件]
F -- 是 --> G[输出生成图像]
F -- 否 --> D
2.13 表格
| 步骤 | 操作 | 代码示例 |
|---|---|---|
| 定义损失函数 | 计算内容损失、风格损失和总损失 |
total_loss(content_image, style_image, combination_image)
|
| 选择优化器 | 选择 Adam 优化器 |
optimizer = tf.keras.optimizers.Adam(learning_rate=0.02)
|
| 迭代优化 | 不断更新生成图像的像素值 |
optimizer.apply_gradients([(grads, combination_image)])
|
时间序列预测与图像风格迁移技术
超级会员免费看
29

被折叠的 条评论
为什么被折叠?



