Resnet for Fashion_Mnist(三)

Resnet for Fashion_Mnist(三)

模型训练

下面给出模型训练、验证的代码,完成后保存模型。

import torch
from torchvision import datasets, models, transforms
import torch.optim as optim
import model
import utils
import time
import argparse
import os
import csv
import MyDataSet

parser = argparse.ArgumentParser()
parser.add_argument("--model", type=str, default='resnet18', help="model")
parser.add_argument("--patience", type=int, default=3, help="early stopping patience")
parser.add_argument("--batch_size", type=int, default=256, help="batch size")
parser.add_argument("--nepochs", type=int, default=200, help="max epochs")
parser.add_argument("--nworkers", type=int, default=4, help="number of workers")
parser.add_argument("--seed", type=int, default=1, help="random seed")
# parser.add_argument("--data", type=str, default='MNIST', help="MNIST, or FashionMNIST")
args = parser.parse_args()

# Set up the device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('Training on {}'.format(device))

# Set seeds. If using numpy this must be seeded too.
torch.manual_seed(args.seed)
if device== 'cuda:0':
    torch.cuda.manual_seed(args.seed)

# Setup folders for saved models and logs
if not os.path.exists('saved-models/'):
    os.mkdir('saved-models/')
if not os.path.exists('logs/'):
    os.mkdir('logs/')

# Setup folders. Each run must have it's own folder. Creates
# a logs folder for each model and each run.
out_dir = 'logs/{}'.format(args.model)
if not os.path.exists(out_dir):
    os.mkdir(out_dir)
run = 0
current_dir = '{}/run-{}'.format(out_dir, run)
while os.path.exists(current_dir):
    run += 1
    current_dir = '{}/run-{}'.format(out_dir, run)
os.mkdir(current_dir)
logfile = open('{}/log.txt'.format(current_dir), 'w')
print(args, file=logfile)



# Define transforms.
train_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
val_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

# Create dataloaders. Use pin memory if cuda.
root = 'E:/Fashion_Mnist/'
train_set = MyDataSet.MyDataset(root=root, datatxt='train.txt', transform=train_transforms)
train_loader = torch.utils.data.DataLoader(train_set, batch_size=args.batch_size,
                              shuffle=True, num_workers=args.nworkers)
val_set = MyDataSet.MyDataset(root=root, datatxt='val.txt', transform=val_transforms)
val_loader = torch.utils.data.DataLoader(val_set, batch_size=args.batch_size,
                            shuffle=True, num_workers=args.nworkers)




def run_model(net, loader, criterion, optimizer, train = True):
    running_loss = 0
    running_accuracy = 0

    # Set mode
    if train:
        net.train()
    else:
        net.eval()


    for i, (X, y) in enumerate(loader):
        # Pass to gpu or cpu
        X, y = X.to(device), y.to(device)

        # Zero the gradient
        optimizer.zero_grad()

        with torch.set_grad_enabled(train):
            output = net(X)
            _, pred = torch.max(output, 1)
            loss = criterion(output, y)

        # If on train backpropagate
        if train:
            loss.backward()
            optimizer.step()

        # Calculate stats
        running_loss += loss.item()
        running_accuracy += torch.sum(pred == y.detach())
    return running_loss / len(loader), running_accuracy.double() / len(loader.dataset)



if __name__ == '__main__':

    # Init network, criterion and early stopping
    net = model.__dict__[args.model]().to(device)
    criterion = torch.nn.CrossEntropyLoss()



    # Define optimizer
    optimizer = optim.Adam(net.parameters())

    # Train the network
    patience = args.patience
    best_loss = 1e4
    writeFile = open('{}/stats.csv'.format(current_dir), 'a')
    writer = csv.writer(writeFile)
    writer.writerow(['Epoch', 'Train Loss', 'Train Accuracy', 'Validation Loss', 'Validation Accuracy'])
    for e in range(args.nepochs):
        start = time.time()
        train_loss, train_acc = run_model(net, train_loader,
                                      criterion, optimizer)
        val_loss, val_acc = run_model(net, val_loader,
                                      criterion, optimizer, False)
        end = time.time()

        # print stats
        stats = """Epoch: {}\t train loss: {:.3f}, train acc: {:.3f}\t
                val loss: {:.3f}, val acc: {:.3f}\t
                time: {:.1f}s""".format(e+1, train_loss, train_acc, val_loss,
                                        val_acc, end - start)
        print(stats)

        # Write to csv file
        writer.writerow([e+1, train_loss, train_acc.item(), val_loss, val_acc.item()])
        # early stopping and save best model
        if val_loss < best_loss:
            best_loss = val_loss
            patience = args.patience
            utils.save_model({
                'arch': args.model,
                'state_dict': net.state_dict()
            }, 'saved-models/{}-run-{}.pth.tar'.format(args.model, run))
        else:
            patience -= 1
            if patience == 0:
                print('Run out of patience!')
                writeFile.close()
                break

好的,我可以为您提供代码实现。在这里,我将使用Keras中的ResNet50预训练模型,并使用Fashion-MNIST数据集对十种服装进行分类。首先,我们需要安装一些必要的库: ``` !pip install tensorflow !pip install keras !pip install matplotlib ``` 接下来,我们将加载数据集并进行预处理: ```python import numpy as np import keras from keras.datasets import fashion_mnist from keras.preprocessing.image import ImageDataGenerator # 数据集路径 (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data() # 将图像转换为RGB格式 x_train = np.repeat(x_train[..., np.newaxis], 3, -1) x_test = np.repeat(x_test[..., np.newaxis], 3, -1) # 批量大小 batch_size = 32 # 数据增强 train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) # 没有数据增强的验证数据生成器 val_datagen = ImageDataGenerator(rescale=1./255) # 训练集生成器 train_generator = train_datagen.flow( x_train, keras.utils.to_categorical(y_train), batch_size=batch_size) # 验证集生成器 val_generator = val_datagen.flow( x_test, keras.utils.to_categorical(y_test), batch_size=batch_size) ``` 接下来,我们将加载ResNet50模型,并对其进行微调,以适应我们的数据集: ```python from keras.applications.resnet50 import ResNet50 from keras.layers import Dense, GlobalAveragePooling2D from keras.models import Model # 加载ResNet50模型,不包括顶层(全连接层) base_model = ResNet50(weights='imagenet', include_top=False) # 添加全局平均池化层 x = base_model.output x = GlobalAveragePooling2D()(x) # 添加全连接层,输出为十个类别 predictions = Dense(10, activation='softmax')(x) # 构建我们需要训练的完整模型 model = Model(inputs=base_model.input, outputs=predictions) # 冻结ResNet50的所有层,以便在训练过程中不更新它们的权重 for layer in base_model.layers: layer.trainable = False ``` 现在,我们可以开始训练模型了: ```python from keras.optimizers import SGD # 编译模型,指定损失函数、优化器和评价指标 model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.001), metrics=['accuracy']) # 训练模型 history = model.fit_generator( train_generator, steps_per_epoch=x_train.shape[0] // batch_size, epochs=10, validation_data=val_generator, validation_steps=x_test.shape[0] // batch_size) ``` 最后,我们可以使用matplotlib库绘制训练和验证的准确率和损失曲线: ```python import matplotlib.pyplot as plt # 绘制训练和验证的准确率曲线 plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('Model accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train', 'Val'], loc='upper left') plt.show() # 绘制训练和验证的损失曲线 plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train', 'Val'], loc='upper left') plt.show() ``` 现在您应该可以使用这些代码实现您的需求了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值