将图片用神经网络提取特征,再与csv中的其他特征进行融合

将图片用神经网络提取的特征和csv文件中的特征进行融合,主要就是要保证读取的图片名字和csv中的名字一致,这样才能保证一致性。随机找了几张图片,举一个例子。

图片的路径为

csv中的特征为

我用vgg16提取特征,然后再与csv中的其他特征进行融合

import torch
import torchvision.models as models
from torch.utils.data import Dataset, DataLoader
import pandas as pd
from torchvision import transforms
from PIL import Image


# 数据集类
class CustomDataset(Dataset):
    def __init__(self, image_folder, csv_file, transform=None):
        self.csv_data = pd.read_csv(csv_file, encoding='gbk')
        self.image_folder = image_folder
        self.transform = transform

        # 获取CSV特征的维度(除文件名列之外的特征数量)
        self.num_csv_features = len(self.csv_data.columns) - 1  # 减去文件名列

    def __len__(self):
        return len(self.csv_data)

    def __getitem__(self, idx):
        img_name = self.csv_data.iloc[idx, 0]  # 图片文件名列在CSV的第一列
        img_path = f"{self.image_folder}/{img_name}"  # 图片路径
        image = Image.open(img_path).convert('RGB')

        if self.transform:
            image = self.transform(image)

        # 返回图像和 CSV 中的其他特征
        return image, torch.tensor(self.csv_data.iloc[idx, 1:], dtype=torch.float32)


# 加载预训练的VGG16模型
vgg16 = models.vgg16(pretrained=True)
vgg16_conv = vgg16.features

# 冻结卷积层的参数
for param in vgg16_conv.parameters():
    param.requires_grad = False


# 自定义全连接层
class CustomNet(torch.nn.Module):
    def __init__(self, input_size, num_csv_features):
        super(CustomNet, self).__init__()
        self.vgg = vgg16_conv
        self.fc = torch.nn.Linear(input_size + num_csv_features, 128)  # 假设128是中间层的大小
        self.fc2 = torch.nn.Linear(128, 2)  # 输出大小为2,代表两个类别

    def forward(self, x, csv_features):
        x = self.vgg(x)
        x = x.view(x.size(0), -1)

        # 拼接图像特征和CSV特征
        x = torch.cat((x, csv_features), dim=1)
        x = self.fc(x)
        x = torch.relu(x)  # 可以添加激活函数如 ReLU

        x = self.fc2(x)
        x = torch.sigmoid(x)  # 使用 Sigmoid 将输出值映射到0到1之间
        return x


# 数据预处理和加载
transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

image_folder = r'D:\edge_download\图像\良性\T2\赵六'
csv_file = r"D:\edge_download\图像\良性\T2\file.csv"

# 创建数据集实例并获取CSV特征的维度
dataset = CustomDataset(image_folder=image_folder, csv_file=csv_file, transform=transform)
num_csv_features = dataset.num_csv_features

dataloader = DataLoader(dataset, batch_size=32, shuffle=True)

# 训练模型
model = CustomNet(input_size=25088, num_csv_features=num_csv_features)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  # 定义设备

model.to(device)  # 将模型移动到设备
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)  # 定义优化器
criterion = torch.nn.BCELoss()  # 定义损失函数为二元交叉熵损失

num_epochs = 10  # 定义迭代次数

for epoch in range(num_epochs):
    for images, csv_features in dataloader:
        images, csv_features = images.to(device), csv_features.to(device)  # 将数据移动到设备

        optimizer.zero_grad()
        outputs = model(images, csv_features)

        # 创建目标张量
        target = torch.zeros_like(outputs)
        target[:, 0] = 1  # 假设第一类别是正例,根据实际情况调整

        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

    print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item()}')

这样就可以了,代码中做的是一个二分类,所以全连接之后用线性层输出为2,使用的损失函数为

torch.nn.BCELoss() ,最后开始训练模型。
  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值