憨批的语义分割7——基于resnet模型的segnet讲解(划分斑马线)

2023-10-31

学习前言

好好学习呀。

在这里插入图片描述

模型部分

什么是Segnet模型

Segnet模型是一个比较基础的语义分割模型,其结构比较简单,在说其结构之前,我们先讲一下convolutional Encoder-Decoder的结构。
主要结构与自编码(Autoencoder)类似,通过编码解码复原图片上每一个点所属的类别。
下图主要是说明利用卷积层编码与解码的过程。
在这里插入图片描述
segnet模型与上述模型类似。
其主要的过程就是,其利用Encoder中提取了多次特征的f4进行处理,利用Decoder进行多次上采样Upsampling2D。最后得到一个具有一定hw的filter数量为n_classes的图层。

什么是Resnet模型

ResNet50有两个基本的块,分别名为Conv Block和Identity Block,其中Conv Block输入和输出的维度是不一样的,所以不能连续串联,它的作用是改变网络的维度;Identity Block输入维度和输出维度相同,可以串联,用于加深网络的。
Conv Block的结构如下:

在这里插入图片描述
Identity Block的结构如下:
在这里插入图片描述
这两个都是残差网络结构。
总的网络结构如下:
在这里插入图片描述

segnet模型的代码实现

segnet模型的代码分为两部分。

1、主干模型resnet。

该部分用于特征提取,实际上就是常规的resnet结构,想要了解resnet结构的朋友们可以看看我的另一篇博客神经网络学习小记录20——ResNet50模型的复现详解

import keras
from keras.models import *
from keras.layers import *
from keras import layers
import keras.backend as K

IMAGE_ORDERING = 'channels_last'
def one_side_pad( x ):
    x = ZeroPadding2D((1, 1), data_format=IMAGE_ORDERING)(x)
    if IMAGE_ORDERING == 'channels_first':
        x = Lambda(lambda x : x[: , : , :-1 , :-1 ] )(x)
    elif IMAGE_ORDERING == 'channels_last':
        x = Lambda(lambda x : x[: , :-1 , :-1 , :  ] )(x)
    return x

def identity_block(input_tensor, kernel_size, filters, stage, block):

    filters1, filters2, filters3 = filters
    
    if IMAGE_ORDERING == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1

    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'
    # 1x1压缩
    x = Conv2D(filters1, (1, 1) , data_format=IMAGE_ORDERING , name=conv_name_base + '2a')(input_tensor)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)
    # 3x3提取特征
    x = Conv2D(filters2, kernel_size , data_format=IMAGE_ORDERING ,
               padding='same', name=conv_name_base + '2b')(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)
    # 1x1扩张特征
    x = Conv2D(filters3 , (1, 1), data_format=IMAGE_ORDERING , name=conv_name_base + '2c')(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
    # 残差网络
    x = layers.add([x, input_tensor])
    x = Activation('relu')(x)
    return x

# 与identity_block最大差距为,其可以减少wh,进行压缩
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):

    filters1, filters2, filters3 = filters
    
    if IMAGE_ORDERING == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1

    conv_name_base = 'res' + str(stage) + block + '_branch'
    bn_name_base = 'bn' + str(stage) + block + '_branch'
    # 1x1压缩
    x = Conv2D(filters1, (1, 1) , data_format=IMAGE_ORDERING  , strides=strides,
               name=conv_name_base + '2a')(input_tensor)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)
    x = Activation('relu')(x)
    # 3x3提取特征
    x = Conv2D(filters2, kernel_size , data_format=IMAGE_ORDERING  , padding='same',
               name=conv_name_base + '2b')(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)
    x = Activation('relu')(x)
    # 1x1扩张特征
    x = Conv2D(filters3, (1, 1) , data_format=IMAGE_ORDERING  , name=conv_name_base + '2c')(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)
    # 1x1扩张特征
    shortcut = Conv2D(filters3, (1, 1) , data_format=IMAGE_ORDERING  , strides=strides,
                      name=conv_name_base + '1')(input_tensor)
    shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)
    # add
    x = layers.add([x, shortcut])
    x = Activation('relu')(x)
    return x


def get_resnet50_encoder(input_height=224 ,  input_width=224 , pretrained='imagenet' , 
                                include_top=True, weights='imagenet',
                                input_tensor=None, input_shape=None,
                                pooling=None,
                                classes=1000):

    assert input_height%32 == 0
    assert input_width%32 == 0

    if IMAGE_ORDERING == 'channels_first':
        img_input = Input(shape=(3,input_height,input_width))
    elif IMAGE_ORDERING == 'channels_last':
        img_input = Input(shape=(input_height,input_width , 3 ))


    if IMAGE_ORDERING == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1


    x = ZeroPadding2D((3, 3), data_format=IMAGE_ORDERING)(img_input)
    x = Conv2D(64, (7, 7), data_format=IMAGE_ORDERING, strides=(2, 2), name='conv1')(x)
    # f1是hw方向压缩一次的结果
    f1 = x
    x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3) , data_format=IMAGE_ORDERING , strides=(2, 2))(x)
    
    
    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')
    # f2是hw方向压缩两次的结果
    f2 = one_side_pad(x )


    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')
    # f3是hw方向压缩三次的结果
    f3 = x 

    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')
    # f4是hw方向压缩四次的结果
    f4 = x 

    x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
    # f5是hw方向压缩五次的结果
    f5 = x 

    x = AveragePooling2D((7, 7) , data_format=IMAGE_ORDERING , name='avg_pool')(x)

    return img_input , [f1 , f2 , f3 , f4 , f5  ]

2、segnet的Decoder解码部分

这一部分对应着上面segnet模型中的解码部分。
其关键就是把获得的特征重新映射到比较大的图中的每一个像素点,用于每一个像素点的分类。

from keras.models import *
from keras.layers import *
from nets.resnet50 import get_resnet50_encoder
IMAGE_ORDERING = 'channels_last'
def segnet_decoder(  f , n_classes , n_up=3 ):

	assert n_up >= 2

	o = f
	o = ( ZeroPadding2D( (1,1) , data_format=IMAGE_ORDERING ))(o)
	o = ( Conv2D(512, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)
	o = ( BatchNormalization())(o)
	# 进行一次UpSampling2D,此时hw变为原来的1/8
	o = ( UpSampling2D( (2,2), data_format=IMAGE_ORDERING))(o)
	o = ( ZeroPadding2D( (1,1), data_format=IMAGE_ORDERING))(o)
	o = ( Conv2D( 256, (3, 3), padding='valid', data_format=IMAGE_ORDERING))(o)
	o = ( BatchNormalization())(o)

	# 进行一次UpSampling2D,此时hw变为原来的1/4
	for _ in range(n_up-2):
		o = ( UpSampling2D((2,2)  , data_format=IMAGE_ORDERING ) )(o)
		o = ( ZeroPadding2D((1,1) , data_format=IMAGE_ORDERING ))(o)
		o = ( Conv2D( 128 , (3, 3), padding='valid' , data_format=IMAGE_ORDERING ))(o)
		o = ( BatchNormalization())(o)

	# 进行一次UpSampling2D,此时hw变为原来的1/4
	o = ( UpSampling2D((2,2)  , data_format=IMAGE_ORDERING ))(o)
	o = ( ZeroPadding2D((1,1)  , data_format=IMAGE_ORDERING ))(o)
	o = ( Conv2D( 64 , (3, 3), padding='valid'  , data_format=IMAGE_ORDERING ))(o)
	o = ( BatchNormalization())(o)

	# 此时输出为h_input/2,w_input/2,nclasses
	o =  Conv2D( n_classes , (3, 3) , padding='same', data_format=IMAGE_ORDERING )( o )
	
	return o 

def _segnet( n_classes , encoder  ,  input_height=416, input_width=608 , encoder_level=3):
	# encoder通过主干网络
	img_input , levels = encoder( input_height=input_height ,  input_width=input_width )

	# 获取hw压缩四次后的结果
	feat = levels[encoder_level]

	# 将特征传入segnet网络
	o = segnet_decoder(feat, n_classes, n_up=3 )

	# 将结果进行reshape
	o = Reshape((int(input_height/2)*int(input_width/2), -1))(o)
	o = Softmax()(o)
	model = Model(img_input,o)

	return model

def resnet50_segnet( n_classes ,  input_height=416, input_width=608 , encoder_level=3):

	model = _segnet( n_classes , get_resnet50_encoder ,  input_height=input_height, input_width=input_width , encoder_level=encoder_level)
	model.model_name = "resnet50_segnet"
	return model

代码测试

将上面两个代码分别保存为resnet50.py和segnet.py。按照如下方式存储:
在这里插入图片描述
此时我们运行test.py的代码:

from nets.segnet import resnet50_segnet
model = resnet50_segnet(n_classes=2,input_height=416, input_width=416)
model.summary()

如果没有出错的话就会得到如下的结果:
在这里插入图片描述

训练部分

训练的是什么

虽然把代码贴上来大家就会点运行然后就可以训练自己的模型,但是我还是想要大家知道,语义分割模型训练的是什么。

1、训练文件详解

这个要从训练文件讲起。

语义分割模型训练的文件分为两部分。
第一部分是原图,像这样:
在这里插入图片描述
第二部分标签,像这样:
在这里插入图片描述
当你们看到这个标签的时候你们会说,我靠,你给我看的什么辣鸡,全黑的算什么标签,其实并不是这样的,这个标签看起来全黑,但是实际上在斑马线的部分其RGB三个通道的值都是1。

其实给你们换一个图你们就可以更明显的看到了。
这是voc数据集中语义分割的训练集中的一幅图:
在这里插入图片描述
这是它的标签。
在这里插入图片描述
为什么这里的标签看起来就清楚的多呢,因为在voc中,其一共需要分21类,所以火车的RGB的值可能都大于10了,当然看得见。

所以,在训练集中,如果像本文一样分两类,那么背景的RGB就是000,斑马线的RGB就是111,如果分多类,那么还会存在222,333,444这样的。这说明其属于不同的类。

2、LOSS函数的组成

关于loss函数的组成我们需要看两个loss函数的组成部分,第一个是预测结果。

	# 此时输出为h_input/2,w_input/2,nclasses
	o =  Conv2D( n_classes , (3, 3) , padding='same', data_format=IMAGE_ORDERING )( o )
	# 将结果进行reshape
	o = Reshape((int(input_height/2)*int(input_width/2), -1))(o)
	o = Softmax()(o)
	model = Model(img_input,o)

其首先利用filter为n_classes的卷积核进行卷积,此时输出为h_input/2,w_input/2,nclasses,对应着每一个hw像素点上的种类。
之后利用Softmax估计属于每一个种类的概率。

其最后预测y_pre其实就是每一个像素点属于哪一个种类的概率

第二个是真实值,真实值是这样处理的。

# 从文件中读取图像
img = Image.open(r".\dataset2\png" + '/' + name)
img = img.resize((int(WIDTH/2),int(HEIGHT/2)))
img = np.array(img)
seg_labels = np.zeros((int(HEIGHT/2),int(WIDTH/2),NCLASSES))
for c in range(NCLASSES):
    seg_labels[: , : , c ] = (img[:,:,0] == c ).astype(int)
seg_labels = np.reshape(seg_labels, (-1,NCLASSES))
Y_train.append(seg_labels)

其将png图先进行resize,resize后其大小与预测y_pre的hw相同,然后读取每一个像素点属于什么种类,并存入。

其最后真实y_true其实就是每一个像素点确实属于哪个种类

最后loss函数的组成就是y_true和y_pre的交叉熵。

训练代码

大家可以在我的github上下载完整的代码。
https://github.com/bubbliiiing/Semantic-Segmentation
数据集的链接为:
链接:https://pan.baidu.com/s/1uzwqLaCXcWe06xEXk1ROWw
提取码:pp6w

1、文件存放方式

如图所示:
在这里插入图片描述
其中img和img_out是测试文件。

2、训练文件

训练文件如下:

from nets.segnet import resnet50_segnet
from keras.optimizers import Adam
from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
from PIL import Image
import keras
from keras import backend as K
import numpy as np

NCLASSES = 2
HEIGHT = 416
WIDTH = 416

def generate_arrays_from_file(lines,batch_size):
    # 获取总长度
    n = len(lines)
    i = 0
    while 1:
        X_train = []
        Y_train = []
        # 获取一个batch_size大小的数据
        for _ in range(batch_size):
            if i==0:
                np.random.shuffle(lines)
            name = lines[i].split(';')[0]
            # 从文件中读取图像
            img = Image.open(r".\dataset2\jpg" + '/' + name)
            img = img.resize((WIDTH,HEIGHT))
            img = np.array(img)
            img = img/255
            X_train.append(img)

            name = (lines[i].split(';')[1]).replace("\n", "")
            # 从文件中读取图像
            img = Image.open(r".\dataset2\png" + '/' + name)
            img = img.resize((int(WIDTH/2),int(HEIGHT/2)))
            img = np.array(img)
            seg_labels = np.zeros((int(HEIGHT/2),int(WIDTH/2),NCLASSES))
            for c in range(NCLASSES):
                seg_labels[: , : , c ] = (img[:,:,0] == c ).astype(int)
            seg_labels = np.reshape(seg_labels, (-1,NCLASSES))
            Y_train.append(seg_labels)

            # 读完一个周期后重新开始
            i = (i+1) % n
        yield (np.array(X_train),np.array(Y_train))

def loss(y_true, y_pred):
    crossloss = K.binary_crossentropy(y_true,y_pred)
    loss = 4 * K.sum(crossloss)/HEIGHT/WIDTH
    return loss

if __name__ == "__main__":
    log_dir = "logs/"
    # 获取model
    model = resnet50_segnet(n_classes=NCLASSES,input_height=HEIGHT, input_width=WIDTH)

    pretrained_url = "https://github.com/fchollet/deep-learning-models/releases/download/v0.2/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5"
    weights_path = keras.utils.get_file( pretrained_url.split("/")[-1] , pretrained_url  )
    model.load_weights(weights_path,by_name=True)

    # model.summary()
    # 打开数据集的txt
    with open(r".\dataset2\train.txt","r") as f:
        lines = f.readlines()

    # 打乱行,这个txt主要用于帮助读取数据来训练
    # 打乱的数据更有利于训练
    np.random.seed(10101)
    np.random.shuffle(lines)
    np.random.seed(None)

    # 90%用于训练,10%用于估计。
    num_val = int(len(lines)*0.1)
    num_train = len(lines) - num_val

    # 保存的方式,3世代保存一次
    checkpoint_period = ModelCheckpoint(
                                    log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
                                    monitor='acc', 
                                    save_weights_only=True, 
                                    save_best_only=True, 
                                    period=1
                                )
    # 学习率下降的方式,acc三次不下降就下降学习率继续训练
    reduce_lr = ReduceLROnPlateau(
                            monitor='acc', 
                            factor=0.5, 
                            patience=3, 
                            verbose=1
                        )
    # 是否需要早停,当val_loss一直不下降的时候意味着模型基本训练完毕,可以停止
    early_stopping = EarlyStopping(
                            monitor='val_loss', 
                            min_delta=0, 
                            patience=10, 
                            verbose=1
                        )
    trainable_layer = 142
    for i in range(trainable_layer):
        model.layers[i].trainable = False
    print('freeze the first {} layers of total {} layers.'.format(trainable_layer, len(model.layers)))
    
    # 交叉熵
    model.compile(loss = loss,
            optimizer = Adam(lr=1e-3),
            metrics = ['accuracy'])
    batch_size = 2
    print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))
    
    # 开始训练
    model.fit_generator(generate_arrays_from_file(lines[:num_train], batch_size),
            steps_per_epoch=max(1, num_train//batch_size),
            validation_data=generate_arrays_from_file(lines[num_train:], batch_size),
            validation_steps=max(1, num_val//batch_size),
            epochs=10,
            initial_epoch=0,
            callbacks=[checkpoint_period, reduce_lr])
    model.save_weights(log_dir+'middle1.h5')
    for i in range(len(model.layers)):
        model.layers[i].trainable = True
    # 交叉熵
    model.compile(loss = loss,
            optimizer = Adam(lr=1e-4),
            metrics = ['accuracy'])
    # 开始训练
    model.fit_generator(generate_arrays_from_file(lines[:num_train], batch_size),
            steps_per_epoch=max(1, num_train//batch_size),
            validation_data=generate_arrays_from_file(lines[num_train:], batch_size),
            validation_steps=max(1, num_val//batch_size),
            epochs=20,
            initial_epoch=10,
            callbacks=[checkpoint_period, reduce_lr])

    model.save_weights(log_dir+'last1.h5')

3、预测文件

预测文件如下:

from nets.segnet import resnet50_segnet
from PIL import Image
import numpy as np
import random
import os
import copy
random.seed(0)
class_colors = [[0,0,0],[0,255,0]]
NCLASSES = 2
HEIGHT = 416
WIDTH = 416
model = resnet50_segnet(n_classes=NCLASSES,input_height=HEIGHT, input_width=WIDTH)
model.load_weights("logs/ep014-loss0.049-val_loss0.075.h5")
imgs = os.listdir("./img")
for jpg in imgs:

    img = Image.open("./img/"+jpg)
    old_img = copy.deepcopy(img)
    orininal_h = np.array(img).shape[0]
    orininal_w = np.array(img).shape[1]

    img = img.resize((WIDTH,HEIGHT))
    img = np.array(img)
    img = img/255
    img = img.reshape(-1,HEIGHT,WIDTH,3)
    pr = model.predict(img)[0]

    pr = pr.reshape((int(HEIGHT/2), int(WIDTH/2), NCLASSES)).argmax(axis=-1)

    seg_img = np.zeros((int(HEIGHT/2), int(WIDTH/2),3))
    colors = class_colors

    for c in range(NCLASSES):
        seg_img[:,:,0] += ( (pr[:,: ] == c )*( colors[c][0] )).astype('uint8')
        seg_img[:,:,1] += ((pr[:,: ] == c )*( colors[c][1] )).astype('uint8')
        seg_img[:,:,2] += ((pr[:,: ] == c )*( colors[c][2] )).astype('uint8')

    seg_img = Image.fromarray(np.uint8(seg_img)).resize((orininal_w,orininal_h))

    image = Image.blend(old_img,seg_img,0.3)
    image.save("./img_out/"+jpg)

训练结果

原图:
在这里插入图片描述
处理后:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

憨批的语义分割7——基于resnet模型的segnet讲解(划分斑马线) 的相关文章

  • 基于MegEngine实现语义分割【附部分源码及模型】

    文章目录 前言 语义分割发展史及意义 一 数据集的准备 二 基于MegEngine的语义分割框架构建 1 引入库 2 CPU GPU配置 3 数据标准化 4 解析数据集到列表中 5 设置数据迭代器 6 获取loader 7 模型构建 8 模
  • 动手学深度学习_全卷积网络 FCN

    全卷积网络 fully convolutional network FCN 顾名思义 网络中完全使用卷积而不再使用全联接网络 全卷积网络之所以能把输入图片经过卷积后在进行尺寸上的还原 就是利用转置卷积实现的 因此 输出的类别预测与输入图像在
  • 图像分类,物体检测,语义分割,实例分割的联系和区别

    从10月中旬开始 科研转为 Object Segment 即物体分割 这属于图像理解范畴 图像理解包含众多 如图像分类 物体检测 物体分割 实例分割等若干具体问题 每个问题研究的范畴是什么 或者说每个问题中 对于某幅图像的处理结果是什么 整
  • 这就是神经网络 9:深度学习-语义分割-FCN、U-Net、SegNet

    FCN 简介 FCN全称是 Fully Convolutional Networks 也就是全卷积网络 这个网络去掉了全连接层 网络结构里只有卷积 池化和反卷积 操作 本文的FCN特指这个语义分割网络 而非广义的全卷积网络 作者在论文里说
  • 高斯混合模型--GMM

    原文 http blog sina com cn s blog 54d460e40101ec00 html 高斯混合模型 GMM Gaussian Mixture Model 统计学习的模型有两种 一种是概率模型 一种是非概率模型 所谓概率
  • 对图片进行膨胀与腐蚀

    操作前的图片 操作后 代码实现 import cv2 import numpy as np from PIL import Image import os import matplotlib pyplot as plt 生成文件夹 def
  • 线段检测M-LSD 已开源

    其中 M LSD tiny最快能以56 8FPS和48 6FPS的速度在手机上实时运行 没错 现在AI在手机上给家具直线描边的速度 可能比你还快 网页版在线demo 为了方便效果展示 作者们还推出了一个网页版demo 基于Python的fl
  • 深度学习模型试跑(七):SETR(Swin-Transformer-Semantic-Segmentation版)

    文章目录 一 前言 二 环境搭建 1 安装cuda和对应的cudnn 2 安装vs2019 3 安装pytorch 4 安装mmcv 和 mmsegmentation 5 拷贝MMSegmentation 三 测试 四 训练 一 前言 源码
  • 语义分割常用数据集整理

    语义分割的数据集分为三类 2D图片 2 5D图片 RGB D 3D图片 每一个类别的数据集都提供了像素级的标签 可以用来评估模型性能 同时其中一部分工作用到了数据增强来增加标签样本的数量 一 2D数据 1 PASCAL Visual Obj
  • 使用MXNet完成一个基于FCN的盲道实时语义分割

    使用MXNet完成一个基于FCN的盲道识别语义分割 一点说明 基本原理 测试集效果 数据标注 训练 基本设置 读入数据 网络构建 开始训练 测试 一点说明 前段时间根据gluon的教程动手学深度学习和同学项目实地拍摄的盲道图片完成了一个基于
  • 语义分割之FCN训练预测自己的数据集

    之前博客PyQt5实现深度学习平台Demo 八 c 调用python方式完成训练和预测 jiugeshao的专栏 CSDN博客中提到 接下来主精力还是先放在深度学习分类 检测 分割算法上面 之前虽然也对各算法做过了解 但没有一一用代码实现过
  • ResNet50及其Keras实现

    如果原理你已经了解 请直接到跳转ResNet50实现 卷积神经网络 第三周作业 Residual Networks v1 你或许看过这篇访问量过12万的博客ResNet解析 但该博客的第一小节ResNet和吴恩达的叙述完全不同 因此博主对这
  • 使用BiseNet从头训练&&微调自己的数据集

    一 代码链接 本次训练采用的是pytorch版本的BiseNet 代码链接为GitHub CoinCheung BiSeNet Add bisenetv2 My implementation of BiSeNet 二 数据格式 数据集分为原
  • CV01-语义分割笔记和两个模型VGG & ResNet的笔记

    目录 一 语义分割 二 VGG模型 2 1 VGG特征提取部分 2 2 VGG图像分类部分 三 ResNet模型 3 1 为什么是ResNet 3 2 1 1卷积调整channel维度大小 3 3 ResNet里的BottleNeck 3
  • 【计算机视觉

    文章目录 一 检测相关 1篇 1 1 SegmentAnything helps microscopy images based automatic and quantitative organoid detection and analy
  • 图像分割2021

    cvpr2022总结 CVPR 2022 图像分割论文大盘点 大林兄的博客 CSDN博客 图像分割最新论文 尽管近年来实例分割取得了长足的进步 但如何设计具有实时性的高精度算法仍然是一个挑战 本文提出了一种实时实例分割框架OrienMask
  • FCN模型训练中遇到的困难

    FCN模型训练中遇到的困难 标签 深度学习FCN神经网络caffe 2017 02 24 10 54 2675人阅读 评论 6 收藏 举报 分类 深度学习 18 版权声明 本文为博主原创文章 未经博主允许不得转载 前前后后大概忙了3个月了
  • 转置卷积(Transposed Convolution)

    文章目录 前言 卷积操作 转置卷积操作 Pytorch中的转置卷积参数 Pytorch转置卷积实验 前言 转置卷积 Transposed Convolution 在语义分割或者对抗神经网络 GAN 中比较常见 其主要作用就是做上采样 UpS
  • 预处理使用 keras 函数 ImageDataGenerator() 生成的图像来训练 resnet50 模型

    我正在尝试训练 resnet50 模型来解决图像分类问题 在我拥有的图像数据集上训练模型之前 我已经加载了 imagenet 预训练权重 我正在使用 keras 函数 flow from directory 从目录加载图像 train da
  • ResNet 原论文及原作者讲解

    ResNet 论文 摘要 1 引入 2 相关工作 残差表示 快捷连接

随机推荐

  • python中expect的作用_expect基本使用方法

    参考 http www cnblogs com lzrabbit p 4298794 html expect是linux系统中可以和子进程进行交互的一个命令 使用它可以做一些自动化工作 python中也有一个模块pexpect 提供了类似的
  • vue导出excel表格

    const file new Blob res data const a document createElement a const fileName 服务完成订单列表 xlsx 下载文件名称 a download fileName a
  • 【无人机】回波状态网络(ESN)在固定翼无人机非线性控制中的应用(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 无人机为执行各种军事和民用任务提供了平台
  • 已迷失在Python的世界里,如此简单,灵活,强大,优美

    最近有一个很好的idea 想快速开发出产品原型 本身做App有4 5年的时间了 移动端应该不是问题 服务端嘛 之前也搞过一段时间 本来想使用Java 但是感觉有点重 开发起来一堆配置 一堆依赖 一堆框架 比较烦它 后来一个朋友跟我说 为什么
  • 浅析MySQL JDBC连接配置上的两个误区

    相信使用MySQL的同学都配置过它的JDBC驱动 多数人会直接从哪里贴一段URL过来 然后稍作修改就上去了 对应的连接池配置也是一样的 很少有人会去细想这每一个参数都是什么含义 今天我们就来聊两个比较常见的配置 是否要开启autoRecon
  • Java8 CompletableFuture多线程异步处理

    测试 GetMapping moreTask public Object moreTask List list new ArrayList lt gt list add A list add B list add C list add D
  • setTimeout()

    定义和用法 setTimeout 方法用于在指定的毫秒数后调用函数或计算表达式 语法 setTimeout code millisec 参数 描述 code 必需 要调用的函数后要执行的 JavaScript 代码串 millisec 必需
  • ue4显示数字_【UE4_光照】UE4中光照的常见问题和解决方案(二)使用手册(转)

    今天是2020年12月10日 星期四 正文共 2818字 40图 预计阅读时间8分 继续分享学习啊 UE4光照烘焙这一块常见问题整理的第二章 光照烘焙第一章 Game艺视界 公众号 Game艺视界 UE4 光照 UE4中光照的常见问题和解决
  • linux安装anaconda(转载)

    Linux安装Anaconda教程 linux anaconda安装 阿飞才可能的博客 CSDN博客1 首先上Linux官网下载最新 对应版本 的Anaconda安装包链接 Anaconda官网下载2 因为我们是在Linux系统下安装Ana
  • android高德地图轨迹偏纠,GitHub - YangHaoyi/DrawTraceDemo: 高德地图轨迹回放带定位纠偏加彩虹渐变线...

    DrawTraceDemo 高德地图轨迹回放带定位纠偏加彩虹渐变线 由于高德自身持续定位存在偏移状况 故摒弃了高德自身的定位点 改用自定义marker点作为定位点 加注轨迹纠偏函数 根据时间判定此次移动是否合乎标准 if currLengt
  • C++分析产品功能数据生成markdown表格代码

    代码功能描述 将各自产品支持的各自功能或特性汇总成一张2维大表 参考下面的输入输出样例 目录 源代码 输入样例 输出样例 粘贴到MarkDown工具内 快速运行 源代码 include
  • ECharts: 绘制立体柱状图【圆柱体】

    绘制这个立体的圆柱体柱状图主要由三块组成 底部 主体 顶部 实现这种效果主要是 ECharts中的 series 属性 通过两种不同类型的图表组合而成 其中里面的柱体渐变色是通过 ECharts中内置的渐变色生成器 echarts grap
  • R语言基础知识汇总

    文章目录 一 常量与变量 1 1 常量 1 2变量 1 3 R数据类型 二 数值型向量及其运算 2 1 数值型向量 2 2 向量运算 2 2 1 标量和标量运算 2 2 2 向量与标量运算 2 2 3 等长向量运算 2 2 4 不等长向量的
  • MySql 高级查询强化学习

    近期从推文上看到一篇面试题上考察的sql编写能力 感觉好多聚合函数的知识还需要巩固一下 特意摘出几个经典的语句在这里给大家分享一下 希望对大家有帮助 建表及插入语句如下 create table student 创建学生表 sid varc
  • 福建师范大学WebPlus Dreamer网站群平台上线(110个站点整体迁移)

    学校自2009年建设网站群平台以来 累计部署站点110个 发布文章10万 篇 根据学校智慧校园建设进度 为规范学校网站安全管理 提高学校网站建设水平 网络与数据中心于2020年6月对网站群平台进行了整体升级 为了避免给各网站管理员造成认知负
  • 智能制造:工业革命的下一步

    随着科技的迅猛发展 智能制造已经成为工业界的热门话题 这一概念不仅仅是一个现代化的制造方法 更是一场工业革命的开始 正在重新定义我们的制造业 1 自动化与机器学习的婚姻 智能制造的核心是自动化和机器学习的结合 自动化使生产过程更高效 更稳定
  • Pyecharts数据可视化分析—折线图

    1 实验介绍 本实验主要介绍折线图理论与基于Python的折线图实现 1 1 实验目的 掌握折线图基本使用场景 使用Python的pyecharts模块实现折线图 1 2 知识点 折线图理论 折线图实现 2 折线图理论 线图介绍 线图也叫折
  • cartopy DLL load failed while importing trace: 找不到指定的模块

    升级依赖包pyproj到3 3 1 完美解决
  • Redis中geospatial(地理位置)数据类型

    geospatial 地理位置 这个功能可以推算地理位置的信息 两地之间的距离 方圆几里的人 geoadd key longitude latitude member 给key中添加元素经纬度和元素名称 经度 longitude 纬度 la
  • 憨批的语义分割7——基于resnet模型的segnet讲解(划分斑马线)

    憨批的语义分割7 基于resnet模型的segnet讲解 划分斑马线 学习前言 模型部分 什么是Segnet模型 什么是Resnet模型 segnet模型的代码实现 1 主干模型resnet 2 segnet的Decoder解码部分 代码测