昇思25天学习打卡营第25 天|Resnet for transition learning

first some params.

python 复制代码
batch_size = 18
image_size = 224
num_epochs = 5
lr = 0.001
momentum = 0.9
workers = 4    #parallel thread

we try to classify dogs and wolves.

def create_dataset_canidae(dataset_path, usage):
    data_set = ds.ImageFolderDataset(dataset_path, 
                                    num_parallel_workers = workers
                                    shuffle = True)
#augmentation    
    mean = [0.485*255, 0.456*255, 0.496*255]
    std = [0.229*255, 0.224*255, 0.225*255]
    scale = 32 
    if usage == 'train':
        trains = [
            vision.RandomCropDecodeResize(size=image_size, scale = (0.08,1.0), ratio = (0.75, 1.333)),
            vision.RandomHorizontalFilp(prob = 0.5),
            vision.Normalize(mean = mean, std = std),
            vision.HWC2CHW()
]
    else :
        trans= [
            vision.Decode(),
            vision.Resize(image_size + scale),
            vision.CenterCrop(image_size),
            vision.Normalize(mean = mean, std = std),
            vision.HWC2CHW()
]
    data_set = data_set.map(
        operations = trans,
        input_columns = 'image',
        num_parallel_workers = workers
)
    #batch op
    data_set = data_set.batch(batch_size)
    return data_set
dataset_train = create_dataset_canidae(data_path_train, 'train')
step_size_train = dataset_train.get_dataset_size()
dataset_val= create_dataest_canidae(data_path_val, 'val')
step_size_val = dataset_val.get_dataset_size()

we visualize the data.

python 复制代码
class_name = {0:'dogs', 1:'wolves'}
plt.figure(figsize = (5,5))
for i in range(4):
    data_image = images[i].asnumpy()
    data_label = labels[i]
    data_image = np.transpose(data_image, (1,2,0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    data_image = std*data_image + mean
    data_image = np.clip(data_image, 0, 1)
    plt.subplot(2,2,i+1)
    plt.imshow(data_image)
    plt.title(class_name[int(labels[i].asnumpy())])
    plt.axis('off')
plt.show()

model.

python 复制代码
weight_init = Normal(mean = 0, sigma = 0.02)
gamma_init = Normal(mean = 1, sigma = 0.02)
python 复制代码
class ResidualBlockBase(nn.Cell):
    expansion : int = 1 #the number of  last conv kernel == that of the first
    def __init__(self, in_channel: int, out_channel: int,
                stride: int = 1, norm: Optional[nn.Cell] = None,
                down_sample: Optional[nn.Cell] = None) ->None:
        super(ResidualBlockBase,self).__init__()
        if not norm:
            self.norm = nn.BatchNorm2d(out_channel)
        else:
            self.norm = norm
        self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size = 3, stride = stride, weight_init = weight_init)
        self.conv2 = nn.Conv2d(in_channel, out_channel, kernel_size =3, weight_init  =weight_init)
        self.relu = nn.ReLU()
        self.down_sample = down_sample
    def construct(self, x):
        identity =x
        out = self.conv1(x) #3x3
        out = self.norm1(out)
        out = self.relu(out)
        out = self.conv2(out)  #3x3
        out = self.norm(out)
        if self.down_sample is not None:
            identity = self.down_sample(x)
        out += identity #shortcut added
        out = self.relu(x)
        return out
class ResidualBlock(nn.Cell):
    expansion = 4 # means the number of last conv is 4 x that of the first
    def __init__(self, in_channel:int, out_channel:int, stride: int = 1, down_sample: Optional[nn.Cell] = None) -> None:
        super(ResidualBlock, self).__init__()
        self.conv1 = nn.Conv2d(in_channel, out_channel, kernel_size =1, weight_init = weight_init)
        self.norm1 = nn.BatchNorm2d(out_channel)
        self.conv2 = nn.Conv2d(out_channel, out_chanmel, kernel_size= 3, stride = stride, weight_init = weight_init)
        self.norm2 = nn.BatchNorm2d(out_channel)
        self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion,
                                    kernel_size = 1, weight_init = weight_init )
        self.norm3 = nn.BatchNorm2d(out_channel*self.expansion)
        self.relu = nn.ReLU()
        self.down_sample = down_sample
    def construct(self, x):
        identity = x
        out = self.conv1(x)
        out = self.norm1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.norm2(out)
        out = self.relu(out)
        out = self.conv3(out)
        out = self.norm3(out)
        if self.down_sample is not None:
            identity = self.down_sample(x)
        out += identity    
        out = self.relu(out)
        return out

def make_layer(last_out_channel, block: Type[Unionp[ResidualBlockBase, ResidualBlock]], channel:int, block_nums:int, stride: int  = 1):
    down_sample = None
    if stride != 1 or last_out_channel != channel * block.expansion:
        down_sample  = nn.SequentialCell([
            nn.Conv2d(last_out_channel, channel*block.expansion, kernel_size = 1, stride = stride, weight_init = weight_init),
            nn.BatchNorm2d(channel*block.expansion, gamma_init = gamma_init)
])
    layers = []
    layers.append(block(last_out_channel,channel, stride= stride, down_sample = down_sample))
    in_channel = channel * block.expansion
    for _ in range(1, block_nums):
        layers.append(block(in_channel, channel))
    return nn.SequentialCell(layers)

construct the resnet50.

python 复制代码
class ResNet(nn.Cell):
    def __init__(self, block:Type[Union[ResidualBlockBase , ResidualBlock]], 
                layer_nums: List[int], num_classes: int, input_channel:int) ->None:
        super(ResNet, self).__init__()
        self.relu = nn.ReLU()    
        self.conv1 = nn.Conv2d(3, 64, kernel_size = 7, stride = 2, weight_init = weight_init)
        self.norm = nn.BatchNorm2d(64)
        self.max_pool = nn.MaxPool2d(kernel_size = 3, stride = 2, pad_mode = 'same')
        self.layer1 = make_layer(64, block, 64, layer_nums[0])
        self.layer2 = make_layer(64* block.expansion, block, 128, layer_nums[1], stride = 2)
        self.layer3 = make_layer(128 * block.expansion, block, 256, layer_nums[2], stride = 2)
        self.layer4 = make_layer(256* block.expansion, block, 512, layer_nums[3], stride = 2)
        self.avg_pool = nn.AvgPool2d()
        self.flatten = nn.Flatten()
        self.fc = nn.Dense(in_channels = input_channel, out_channels = num_classes)
    def construct(self, x):
        x = self.conv1(x)    
        x = self.norm(x)
        x= self.relu(x)    
        x = self.max_pool(x)
        x= self.layer1(x)
        x = self.layer2(x)    
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.avg_pool (x)
        x = self.flatten(x)
        x = self.fc(x)
        return x
def _resnet(model_url:str, block:Type[Union[ResidualBlockBase, ResidualBlock]],
                layers:List[int] , num_classes:int, pretrained:bool, pretrained_ckpt: str, input_channel:int):
        model = ResNet(block, layers, num_classes, input_channel)
        if pretrained:
            download(url = model_url, path =pretrained_ckpt, replace = True)
            param_dict = load_checkpoint(pretrained_ckpt)
            load_param_into_net(model, param_dict)
        return model
def resnet50(num_classe: int  = 1000, pretrained: bool = False):
        resnet50_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt"
        resnet50_ckpt = './LoadPretrainedModel/resent50_224_new.ckpt'
        return _resnet(resnet50_url, ResidualBlock, [3,4,6,3], num_classes, pretrained, resnet50_ckpt, 2048)
##we freeze the backbone and finetune
net_work = resnet50(pretrained= True)
in_channels= net_work.fc.in_channels # the input of dense layer
head = nn.Dense(in_channels, 2) #2:dogs and wolves
net_work.fc  = head # reset
avg_pool = nn.AvgPool2d(kernel_size = 7)
net_work.avg_pool  =avg_pool#reset
for param in net_work.get_parameters():
        if param.name not in ['fc.weight', 'fc.bias']:
            param.requires_grad = False
opt = nn.Momentum(params = net_work.work.trainable_params(), learning_rate = lr, momentum = 0.5)
loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse  = True , reduction = 'mean')
def forward_fn (inputs, targets):
        logits = net_work(inputs)
        loss = loss_fn(logits, targets)
        return loss
grad_fn = ms.value_and_grad(forward_fn, None, opt.parameters)
def train_step(inputs, targets):
    loss, grads = grad_fn (inputs, targets)
    opt(grads)
    return loss
model1 = train.Model(net_work, loss_fn, opt, metrics = {'Accuarcy':train_Accuracy()})

start to train the model. Time has been dramatically saved since it is based on rhe pretrained model.

python 复制代码
dataset_train = create_dataset_canidae(data_path_train, 'train')
step_size_train = dataset_train.get_dataset_size()
dataset_val = create_dataset_canidae(data_path_val, 'val')
step_size_val = dataset_val.get_dataset_size()

num_epochs = 5
data_loader_train = dataset_train.create_tuple_iterator(num_epochs= num_epochs)
data_loader_val  = dataset_val.create_tuple_iterator(num_epochs = num_epochs)
best_ckpt_dir = './BestCheckpoint'
best_ckpt_path = './BestCheckpoint/resnet50-best-freezing-param.ckpt'
python 复制代码
best_acc =0 
for epoch in range(num_epochs):
    losses = []
    net_work.set_train()
    epoch_start = time.time()
    for i , (images, labels) in enumerate(data_loader_train):
        labels = labels.astype(float32)
        loss = train_step(images, labels)
        losses.append(loss)

acc = model1.eval(dataset_val)['Accuracy']
epoch_end = time.time()
epochs_seconds = (epoch_end - epoch_start) * 1000
step_seconds = epoch_seconds / step_size_train
print('-' * 20)
print('Epoch:[%3d/%3d], Average Train Loss:[%5.3f], Accuarcy:[%5.3f]' %(epoch + 1, num_epochs, sum(losses) / len(losses), acc))
print('epoch time: %5.3f ms, per step time : %5.3f ms' %(epoch_seconds, step_seconds))
if acc> best_acc:    
    best_acc =acc
    if not os.path.exists(best_ckpt_dir):
        os.mkdir(best_ckpt_dir)
    ms.save_checkpoint(net_work, best_ckpt_path)
print('=' * 80)
print(f'End of validation the best Accuracy is :{best_acc: 5.3f},'
        f'save the best ckpt file in {best_ckpt_path}', flush = True)

we visualize the prediction to make blue color represents correction.

python 复制代码
def visualize_model(best_ckpt_path, val_ds):
    net = resnet50()
    in_channels = net.fc.in_channels
    head = nn.Dense(in_channels, 2)
    net.fc = head
    avg_pool = nn.AvgPool2d(kernel_size = 7)
    net.fc = head
    avg_pool = nn.AvgPool2d(kernel_size = 7)
    net.avg_pool = avg_pool
    param_dict = ms.load_checkpoint(best_ckpt_path)
    ms.load_param_into_net(net, param_dict)
    mdoel = train.Model(net)
    data = next(val_ds.create_dict_iterator())
    images = data['image'].asnumpy()
    labels = data['label'].asnumpy()
    class_name = {0:'dogs', 1:"wolves"}
    output = model.predict(ms.Tensor(data['image']))
    pred = np.argmax(output.asnumpy(), axis = 1)
    plt.figure(figsize = (5,5))
    for i in range(4):
        plt.subplot(2,2,i+1)
        color = 'blue' if pred[i] == labels[i] else 'red'
        picture_show = np.transpose(images[i], (1,2,0))
        mean = np.array([0.485,0.456,0.406])
        std = np.array([0.229, 0.224, 0.225])
        picture_show = std*picture_show + mean
        picture_show = np.clip(picture_show, 0,1)
        plt.imshow(picture_show)
        plt.axis('off')
    plt.show()

visualize_model(best_ckpt_path, dataset_val)

相关推荐
sanguine__2 分钟前
java学习-集合
学习
lxlyhwl2 分钟前
【STK学习】part2-星座-目标可见性与覆盖性分析
学习
nbsaas-boot3 分钟前
如何利用ChatGPT加速开发与学习:以BPMN编辑器为例
学习·chatgpt·编辑器
CV学术叫叫兽42 分钟前
一站式学习:害虫识别与分类图像分割
学习·分类·数据挖掘
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
一棵开花的树,枝芽无限靠近你1 小时前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek2 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
二进制_博客2 小时前
Flink学习连载文章4-flink中的各种转换操作
大数据·学习·flink
codebolt3 小时前
ADS学习记录
学习
Komorebi.py4 小时前
【Linux】-学习笔记05
linux·笔记·学习