1.迁移学习(Transfer Learning)是什么?
简而言之,迁移学习(Transfer Learning)是一种机器学习方法,就是把为任务 A 开发的模型作为初始点 ,重新使用在为任务 B 开发模型的过程中。
迁移学习是通过从已学习的相关任务中转移里面的知识来改进学习的新任务,例如,我们可能会发现学习识别苹果可能有助于识别梨,或者学习弹奏电子琴可能有助于学习钢琴。
找到目标问题的相似性,迁移学习任务就是从相似性出发,将旧领域(domain)学习过的模型应用在新领域上。我们通常希望利用源领域的知识和特征来辅助目标任务的学习。
2.为什么要进行迁移学习?
1、大数据与少标注的矛盾: 虽然有大量的数据,但往往都是没有标注的,无法训练机器学习模型。人工进行数据标定太耗时**(非监督)**。
2、大数据与弱计算的矛盾(本身很穷): 普通人无法拥有庞大的数据量与计算资源。因此需要借助于模型的迁移。
3.如何进行迁移学习(How to transfer?)
1.选择源领域和目标领域:
确定你要解决的目标任务(目标领域)。另外,选择一个与目标任务相关但不完全相同的任务作为源领域。源领域通常具有足够的数据和标签,可以帮助我们通过这个模型提取出所需的知识去学习通用的特征。
2.选择模型架构:
模型架构的设计旨在从源领域中提取知识特征 ,然后将这些特征应用到目标任务中。我们通常希望利用源领域的知识和特征来辅助目标任务的学习,特别是当目标任务的数据较少或者目标领域与源领域有一定的相似性时。
根据任务的复杂度和数据情况选择合适的模型架构,可以是经典的卷积神经网络(如VGG、ResNet等)、循环神经网络(如LSTM、GRU等)、生成对抗网络(如GANs)等。
3.冻结部分模型参数:
如果源领域和目标领域之间的特征差异较大 ,可以选择冻结源领域模型的部分参数,只训练部分参数以适应目标任务。这有助于防止源领域特定的特征影响目标任务的学习。
4.选择合适的损失函数:
根据目标任务的性质选择合适的损失函数,如分类任务可以选择交叉熵损失函数,回归任务可以选择**均方误差损失函数(MSE)**等。
5.进行数据预处理:
比如进行数据归一化**(比如:对源领域和目标领域的图片数据进行归一化处理,确保它们的像素值处于相同的量级),对图像数据进行降噪处理,去除可能存在的图像噪声 (比如:可以采用图像平滑算法(如高斯模糊)对图像进行平滑处理,降低噪声的影响),另外还有数据清洗(检测并处理源领域和目标领域数据中的缺失值和异常值,确保数据质量良好)** 等等。
python
import pandas as pd
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split
# 假设我们有一个CSV文件包含汽车数据,其中有数值型和分类型特征
# 读取数据
data = pd.read_csv('car_data.csv')
# 数据清洗(处理缺失值)
data = data.dropna()
# 数据预处理(数值型特征归一化,分类型特征编码)
# 数值型特征归一化
scaler = StandardScaler()
numerical_features = ['horsepower', 'weight', 'acceleration']
data[numerical_features] = scaler.fit_transform(data[numerical_features])
# 分类型特征编码
label_encoder = LabelEncoder()
data['origin'] = label_encoder.fit_transform(data['origin'])
# 划分训练集和测试集
X = data.drop('mpg', axis=1) # 特征矩阵
y = data['mpg'] # 目标变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 查看预处理后的数据
print(X_train.head())
print(y_train.head())
4.When to transfer: 什么时候可以进行迁移
5.迁移学习的一些概念
1.基本定义:
域(Domain):数据特征和特征分布组成,是学习的主体
源域 (Source domain):已有知识的域
目标域 (Target domain):要进行学习的域
任务 (Task):由目标函数和学习结果组成,是学习的结果
2.按特征空间分类:
同构迁移学习(Homogeneous TL): 源域和目标域的特征空间相同
异构迁移学习(Heterogeneous TL):源域和目标域的特征空间不同
3.按迁移情景分类:
归纳式迁移学习(Inductive TL):源域和目标域的学习任务不同
直推式迁移学习(Transductive TL):源域和目标域不同,学习任务相同
无监督迁移学习(Unsupervised TL):源域和目标域均没有标签
4.按迁移方法分类:
基于样本的迁移 (Instance based TL): 通过权重重用源域和目标域的样例进行迁移
基于样本的迁移学习方法 (Instance based Transfer Learning) 根据一定的权重生成规则,对数据样本进行重用,来进行迁移学习。下图形象地表示了基于样本迁移方法的思想源域中存在不同种类的动物,如狗、鸟、猫等,目标域只有狗这一种类别。在迁移时,为了最大限度地和目标域相似,我们可以人为地提高源域中属于狗这个类别的样本权重。
**基于特征的迁移 (Feature based TL):**将源域和目标域的特征变换到相同空间
基于特征的迁移方法 (Feature based Transfer Learning) 是指将通过特征变换的方式互相迁移,来减少源域和目标域之间的差距;或者将源域和目标域的数据特征变换到统一特征空间中,然后利用传统的机器学习方法进行分类识别。根据特征的同构和异构性,又可以分为同构和异构迁移学习。下图很形象地表示了两种基于特 征的迁移学习方法。
**基于模型的迁移 (Parameter based TL):**利用源域和目标域的参数共享模型
基于模型的迁移方法 (Parameter/Model based Transfer Learning) 是指从源域和目标域中找到他们之间共享的参数信息,以实现迁移的方法。这种迁移方式要求的假设条件是: 源域中的数据与目标域中的数据可以共享一些模型的参数。下图形象地表示了基于模型的迁移学习方法的基本思想。
**基于关系的迁移 (Relation based TL):**利用源域中的逻辑网络关系进行迁移
基于关系的迁移学习方法 (Relation Based Transfer Learning) 与上述三种方法具有截然不同的思路。这种方法比较关注源域和目标域的样本之间的关系。下图形象地表示了不 同领域之间相似的关系。
6.什么是FineTune微调
微调是迁移学习的一种技术,它通常指的是在已经预训练好的模型基础上,对模型的部分或全部参数进行调整,以适应新任务的需求。微调可以在源域数据上进行,也可以在目标域数据上进行。
举个例子: 假设你有一个在大规模图像数据集上预训练好的卷积神经网络(CNN),用于识别不同物体的图片。现在你有一个小型的数据集,包含了特定类型的物体图片,比如狗和猫。你可以使用迁移学习,将预训练的CNN模型作为基础模型,在你的小型数据集上进行微调,以便让模型学习到狗和猫的识别任务。
python
from tensorflow.keras.applications import VGG16 # 导入VGG16模型
from tensorflow.keras.models import Sequential # 导入Sequential模型
from tensorflow.keras.layers import Dense, Flatten, Dropout # 导入Dense、Flatten和Dropout层
from tensorflow.keras.optimizers import Adam # 导入Adam优化器
from tensorflow.keras.preprocessing.image import ImageDataGenerator # 导入ImageDataGenerator用于数据增强
# 加载预训练的VGG16模型,不包含顶层分类器
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# 冻结VGG16的卷积层,只微调顶层分类器
for layer in base_model.layers:
layer.trainable = False
# 添加自定义的顶层分类器
model = Sequential([
base_model, # 添加预训练的VGG16模型作为基础模型
Flatten(), # 展平层
Dense(256, activation='relu'), # 全连接层1,256个神经元,激活函数为ReLU
Dropout(0.5), # Dropout层,防止过拟合
Dense(2, activation='softmax') # 全连接层2,2个输出类别:狗和猫,激活函数为softmax
])
# 编译模型
model.compile(optimizer=Adam(learning_rate=0.0001), # 使用Adam优化器,学习率设为0.0001
loss='categorical_crossentropy', # 使用交叉熵损失函数
metrics=['accuracy']) # 评估指标为准确率
# 数据增强
train_datagen = ImageDataGenerator(
rescale=1./255, # 像素值缩放到0~1之间
rotation_range=20, # 随机旋转角度范围为20度
width_shift_range=0.2, # 水平随机偏移范围为20%
height_shift_range=0.2, # 垂直随机偏移范围为20%
shear_range=0.2, # 剪切强度范围为20%
zoom_range=0.2, # 缩放范围为20%
horizontal_flip=True, # 水平翻转
fill_mode='nearest' # 填充像素的方式为最近像素
)
# 加载训练数据和验证数据
train_generator = train_datagen.flow_from_directory(
'train_data_dir', # 训练数据目录
target_size=(224, 224), # 图像尺寸设为224x224
batch_size=32, # 批量大小为32
class_mode='categorical' # 多分类任务
)
validation_generator = train_datagen.flow_from_directory(
'validation_data_dir', # 验证数据目录
target_size=(224, 224), # 图像尺寸设为224x224
batch_size=32, # 批量大小为32
class_mode='categorical' # 多分类任务
)
# 进行模型训练
model.fit(
train_generator, # 训练数据生成器
steps_per_epoch=train_generator.samples // 32, # 每个epoch的步数
epochs=10, # 迭代次数为10
validation_data=validation_generator, # 验证数据生成器
validation_steps=validation_generator.samples // 32 # 每个epoch的验证步数
)
# 保存微调后的模型
model.save('fine_tuned_model.h5')