一.模型介绍
MMVID(多模态变体信息融合模型)是一种用于多模态数据融合的模型。它的目标是将来自不同模态(如图像、文本、音频等)的信息结合起来,以提取更丰富、更准确的特征表示。
MMVID模型的核心思想是通过学习模态间的相关性和互补性来实现融合。它通常由以下几个组件构成:
1. 模态特征提取器:针对每个模态,使用适当的深度学习模型(如卷积神经网络、循环神经网络等)来提取高层次的特征表示。
2. 模态间关联建模:通过引入注意力机制或相关性学习方法,学习不同模态之间的相关性,以捕捉它们之间的关联信息。
3. 特征融合:将不同模态的特征进行融合,可以通过简单的拼接、加权平均等方式来实现。
4. 全局特征学习:将融合后的特征输入到全局特征学习层,进一步提取更高级别的语义信息。
5. 任务特定层:根据具体任务的需求,可以添加适当的任务特定层,如分类器、回归器等。
MMVID模型的优势在于能够充分利用多模态数据中不同模态之间的互补性,提升对于复杂任务的建模能力。它被广泛应用于多媒体分析、情感分析、图像与文本生成等领域。
二.数据集的处理
下载数据集:从官方网站下载数据集的图像、标签和注释文件。
数据预处理:对图像进行预处理,如裁剪、缩放、归一化等操作,以及对标签进行预处理,如颜色映射、编码等操作。
数据增强:对图像进行数据增强操作,如随机翻转、旋转、裁剪等操作,以增加数据的多样性和泛化能力。
划分数据集:将数据集划分为训练集、验证集和测试集,以用于模型的训练、验证和测试。
三.模型训练
模型构建的核心代码,话不多说,show me the code!
class Trainer(object):
def __init__(self, args):
self.args = args
# image transform
input_transform =
transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([.485, .456, .406], [.229, .224, .225]),
])
# dataset and dataloader
data_kwargs = {'transform': input_transform, 'base_size': args.base_size, 'crop_size': args.crop_size}
train_dataset =
get_segmentation_dataset(args.dataset, split=args.train_split, mode='train', **data_kwargs)
val_dataset =
get_segmentation_dataset(args.dataset, split='val', mode='val', **data_kwargs)
self.train_loader = data.DataLoader(dataset=train_dataset,
batch_size=args.batch_size,
shuffle=True,
drop_last=True)
self.val_loader = data.DataLoader(dataset=val_dataset,
batch_size=1,
shuffle=False)
# create network
self.model = get_fast_scnn(dataset=args.dataset, aux=args.aux)
if torch.cuda.device_count() > 1:
self.model = torch.nn.DataParallel(self.model, device_ids=[0, 1, 2])
self.model.to(args.device)
# resume checkpoint if needed
if args.resume:
if os.path.isfile(args.resume):
name, ext = os.path.splitext(args.resume)
assert ext == '.pkl' or '.pth', 'Sorry only .pth and .pkl files supported.'
print('Resuming training, loading {}...'.format(args.resume))
self.model.load_state_dict(torch.load(args.resume,
map_location=lambda storage, loc:
storage))
# create criterion
self.criterion = MixSoftmaxCrossEntropyOHEMLoss(aux=args.aux, aux_weight=args.aux_weight,
ignore_index=-1).to(args.device)
# optimizer
self.optimizer = torch.optim.SGD(self.model.parameters(),
lr=args.lr,
momentum=args.momentum,
weight_decay=args.weight_decay)
# lr scheduling
self.lr_scheduler = LRScheduler(mode='poly', base_lr=args.lr, nepochs=args.epochs,
iters_per_epoch=len(self.train_loader), power=0.9)
# evaluation metrics
self.metric = SegmentationMetric(train_dataset.num_class)
self.best_pred = 0.0
def train(self):
cur_iters = 0
start_time = time.time()
for epoch in range(self.args.start_epoch, self.args.epochs):
self.model.train()
for i, (images, targets) in enumerate(self.train_loader):
cur_lr = self.lr_scheduler(cur_iters)
for param_group in self.optimizer.param_groups:
param_group['lr'] = cur_lr
images = images.to(self.args.device)
targets = targets.to(self.args.device)
outputs = self.model(images)
loss = self.criterion(outputs, targets)
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
cur_iters += 1
if cur_iters % 10 == 0:
print('Epoch: [%2d/%2d] Iter [%4d/%4d] || Time: %4.4f sec || lr: %.8f || Loss: %.4f' % (
epoch, args.epochs, i + 1, len(self.train_loader),
time.time() - start_time, cur_lr,
loss.item()))
if self.args.no_val:
# save every
epoch
save_checkpoint(self.model, self.args, is_best=False)
else:
self.validation(epoch)
save_checkpoint(self.model, self.args, is_best=False)
def validation(self, epoch):
is_best = False
self.metric.reset()
self.model.eval()
for i, (image, target) in enumerate(self.val_loader):
image =
image.to(self.args.device)
outputs = self.model(image)
pred = torch.argmax(outputs[0], 1)
pred =
pred.cpu().data.numpy()
self.metric.update(pred, target.numpy())
pixAcc,
mIoU = self.metric.get()
print('Epoch %d, Sample %d, validation pixAcc: %.3f%%, mIoU: %.3f%%' % (
epoch, i + 1, pixAcc * 100, mIoU * 100))
new_pred = (pixAcc +
mIoU) / 2
if new_pred > self.best_pred:
is_best = True
self.best_pred = new_pred
save_checkpoint(self.model, self.args, is_best)
def save_checkpoint(model, args, is_best=False):
"""Save Checkpoint"""
directory =
os.path.expanduser(args.save_folder)
if not os.path.exists(directory):
os.makedirs(directory)
filename = '{}_{}.pth'.format(args.model, args.dataset)
save_path = os.path.join(directory,
filename)
torch.save(model.state_dict(),
save_path)
if is_best:
best_filename = '{}_{}_best_model.pth'.format(args.model, args.dataset)
best_filename =
os.path.join(directory, best_filename)
shutil.copyfile(filename,
best_filename)
其中,我有一个训练函数和一个验证函数,最后在一个判断语句中if is_best,如果是最好的模型,就将其保存下来,避免模型过拟合导致效果变差。
四.细节备注
可以在项目中直接运行demo.py文件,来调用我保存好的模型权重,然后得到输出。在模型中我广泛使用intel架构
使用Intel架构的好处:
统一性:oneAPI提供了一套统一的编程模型,使开发人员能够使用相同的代码在不同的硬件上运行应用程序。这种统一性简化了开发过程,减少了维护多个代码版本的复杂性。
可移植性:oneAPI支持跨多种硬件平台的开发。开发人员可以编写一次代码,然后在不同的处理器和加速器上进行优化和执行,从而实现应用程序的高性能。
开放性:oneAPI是开放的,并且符合行业标准。它采用了许多开放标准和接口,使开发人员能够与各种硬件和软件组件进行集成。
五.测试总结
可以通过不同的文本以及图像的初稿,可以自动生成许多描述风格的图片,这样就可以做到保持可控并且效率更高,得到更好的生成效果!
以上就是我本次项目的所有重点工作的梳理,更多细节可以查看我的代码,我本人一直秉承少说多写,没有什么能够比代码有说服力。在本次比赛中也再次感谢Intel官方提供的分析工具和模型结构加速工具,让我的模型构建起来更加的轻松。