tensorfow2.0 实现 Resnet

import  tensorflow as tf
from    tensorflow import keras
from    tensorflow.keras import layers, Sequential



class BasicBlock(layers.Layer):

    def __init__(self, filter_num, stride=1):
        super(BasicBlock, self).__init__()

        self.conv1 = layers.Conv2D(filter_num, (3, 3), strides=stride, padding='same')
        self.bn1 = layers.BatchNormalization()
        self.relu = layers.Activation('relu')

        self.conv2 = layers.Conv2D(filter_num, (3, 3), strides=1, padding='same')
        self.bn2 = layers.BatchNormalization()

        if stride != 1:
            self.downsample = Sequential()
            self.downsample.add(layers.Conv2D(filter_num, (1, 1), strides=stride))
        else:
            self.downsample = lambda x:x



    def call(self, inputs, training=None):

        # [b, h, w, c]
        out = self.conv1(inputs)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        identity = self.downsample(inputs)

        output = layers.add([out, identity])
        output = tf.nn.relu(output)

        return output


class ResNet(keras.Model):


    def __init__(self, layer_dims, num_classes=100): # [2, 2, 2, 2]
        super(ResNet, self).__init__()

        self.stem = Sequential([layers.Conv2D(64, (3, 3), strides=(1, 1)),
                                layers.BatchNormalization(),
                                layers.Activation('relu'),
                                layers.MaxPool2D(pool_size=(2, 2), strides=(1, 1), padding='same')
                                ])

        self.layer1 = self.build_resblock(64,  layer_dims[0])
        self.layer2 = self.build_resblock(128, layer_dims[1], stride=2)
        self.layer3 = self.build_resblock(256, layer_dims[2], stride=2)
        self.layer4 = self.build_resblock(512, layer_dims[3], stride=2)

        # output: [b, 512, h, w],
        self.avgpool = layers.GlobalAveragePooling2D()
        self.fc = layers.Dense(num_classes)





    def call(self, inputs, training=None):

        x = self.stem(inputs)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        # [b, c]
        x = self.avgpool(x)
        # [b, 100]
        x = self.fc(x)

        return x



    def build_resblock(self, filter_num, blocks, stride=1):

        res_blocks = Sequential()
        # may down sample
        res_blocks.add(BasicBlock(filter_num, stride))

        for _ in range(1, blocks):
            res_blocks.add(BasicBlock(filter_num, stride=1))

        return res_blocks


def resnet18():
    return ResNet([2, 2, 2, 2])


def resnet34():
    return ResNet([3, 4, 6, 3])

网络训练

import  tensorflow as tf
from    tensorflow.keras import layers, optimizers, datasets, Sequential
import  os
from    test.resnet import resnet18

os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
tf.random.set_seed(2345)





def preprocess(x, y):
    # [-1~1]
    x = tf.cast(x, dtype=tf.float32) / 255. - 0.5
    y = tf.cast(y, dtype=tf.int32)
    return x,y


(x,y), (x_test, y_test) = datasets.cifar100.load_data()
y = tf.squeeze(y, axis=1)
y_test = tf.squeeze(y_test, axis=1)
print(x.shape, y.shape, x_test.shape, y_test.shape)


train_db = tf.data.Dataset.from_tensor_slices((x,y))
train_db = train_db.shuffle(1000).map(preprocess).batch(512)

test_db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
test_db = test_db.map(preprocess).batch(512)

sample = next(iter(train_db))
print('sample:', sample[0].shape, sample[1].shape,
      tf.reduce_min(sample[0]), tf.reduce_max(sample[0]))


def main():

    # [b, 32, 32, 3] => [b, 1, 1, 512]
    model = resnet18()
    model.build(input_shape=(None, 32, 32, 3))
    model.summary()
    optimizer = optimizers.Adam(lr=1e-3)

    for epoch in range(500):

        for step, (x,y) in enumerate(train_db):

            with tf.GradientTape() as tape:
                # [b, 32, 32, 3] => [b, 100]
                logits = model(x)
                # [b] => [b, 100]
                y_onehot = tf.one_hot(y, depth=100)
                # compute loss
                loss = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
                loss = tf.reduce_mean(loss)

            grads = tape.gradient(loss, model.trainable_variables)
            optimizer.apply_gradients(zip(grads, model.trainable_variables))

            if step %50 == 0:
                print(epoch, step, 'loss:', float(loss))



        total_num = 0
        total_correct = 0
        for x,y in test_db:

            logits = model(x)
            prob = tf.nn.softmax(logits, axis=1)
            pred = tf.argmax(prob, axis=1)
            pred = tf.cast(pred, dtype=tf.int32)

            correct = tf.cast(tf.equal(pred, y), dtype=tf.int32)
            correct = tf.reduce_sum(correct)

            total_num += x.shape[0]
            total_correct += int(correct)

        acc = total_correct / total_num
        print(epoch, 'acc:', acc)



if __name__ == '__main__':
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: TensorFlow 2.可以通过使用Keras API来实现ResNet50模型。ResNet50是一种深度卷积神经网络,由50个卷积层组成,用于图像分类和目标检测等任务。 以下是使用TensorFlow 2.和Keras API实现ResNet50的示例代码: ```python import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.layers import Dense, Flatten from tensorflow.keras.models import Model # 加载ResNet50模型 resnet = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3)) # 冻结ResNet50模型的所有层 for layer in resnet.layers: layer.trainable = False # 添加自定义输出层 x = resnet.output x = Flatten()(x) x = Dense(1024, activation='relu')(x) predictions = Dense(100, activation='softmax')(x) # 构建新模型 model = Model(inputs=resnet.input, outputs=predictions) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) ``` 在上面的代码中,我们首先加载了预训练的ResNet50模型,并将其所有层都冻结。然后,我们添加了自定义的输出层,并使用Keras API构建了一个新模型。最后,我们编译了模型并指定了优化器、损失函数和评估指标。 接下来,我们可以使用该模型进行训练和预测。例如,我们可以使用以下代码加载图像数据集并训练模型: ```python from tensorflow.keras.preprocessing.image import ImageDataGenerator # 加载图像数据集 train_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( 'data/train', target_size=(224, 224), batch_size=32, class_mode='categorical') # 训练模型 model.fit_generator( train_generator, steps_per_epoch=200, epochs=50) ``` 在上面的代码中,我们使用Keras的ImageDataGenerator类加载了图像数据集,并指定了训练集的目录、图像大小和批量大小等参数。然后,我们使用fit_generator()方法训练模型,并指定了训练集的步数和训练轮数等参数。 最后,我们可以使用以下代码对新数据进行预测: ```python import numpy as np from tensorflow.keras.preprocessing import image # 加载测试图像 img_path = 'data/test/cat.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=) x = preprocess_input(x) # 预测图像类别 preds = model.predict(x) print('Predicted:', decode_predictions(preds, top=3)[]) ``` 在上面的代码中,我们使用Keras的image模块加载了测试图像,并将其转换为NumPy数组。然后,我们使用预处理函数preprocess_input()对图像进行预处理,并使用模型的predict()方法对图像进行预测。最后,我们使用decode_predictions()函数将预测结果转换为可读的格式。 ### 回答2: Tensorflow是一种流行的深度学习框架,它可以用来实现各种神经网络模型,包括ResNet。首先,需要安装Tensorflow2.0版本。进入Python环境,可以用命令`pip install tensorflow==2.0`来安装。 ResNet是一种广泛使用的深度卷积神经网络结构,其核心思想是使用残差模块来缓解深层网络中的梯度消失问题,以提高训练效果和模型的表现力。ResNet有很多变种,包括ResNet-50、ResNet-101等。这里以ResNet-50为例进行实现。 首先,需要导入必要的库,包括Tensorflow和相关的Keras模块: ``` import tensorflow as tf from tensorflow import keras from tensorflow.keras.layers import Conv2D, BatchNormalization, ReLU, Add, AvgPool2D, Dense, Flatten ``` 然后,定义ResNet-50的基本残差模块,包含两个卷积层和一个残差连接: ``` class ResidualBlock(keras.Model): def __init__(self, in_channels, out_channels, strides=1, use_bias=False): super(ResidualBlock, self).__init__() self.conv1 = keras.Sequential([ Conv2D(out_channels // 4, kernel_size=1, strides=1, use_bias=False), BatchNormalization(), ReLU() ]) self.conv2 = keras.Sequential([ Conv2D(out_channels // 4, kernel_size=3, strides=strides, padding='same', use_bias=False), BatchNormalization(), ReLU() ]) self.conv3 = keras.Sequential([ Conv2D(out_channels, kernel_size=1, strides=1, use_bias=False), BatchNormalization(), ]) self.shortcut = keras.Sequential() if strides != 1 or in_channels != out_channels: self.shortcut = keras.Sequential([ Conv2D(out_channels, kernel_size=1, strides=strides, use_bias=False), BatchNormalization(), ]) self.relu = ReLU() def call(self, inputs): x = self.conv1(inputs) x = self.conv2(x) x = self.conv3(x) shortcut = self.shortcut(inputs) x = Add()([x, shortcut]) x = self.relu(x) return x ``` 接着,定义ResNet-50的整体结构,包含多个残差模块和全连接层: ``` class ResNet(keras.Model): def __init__(self, block, num_blocks, num_classes): super(ResNet, self).__init__() self.in_channels = 64 self.conv1 = keras.Sequential([ Conv2D(64, kernel_size=7, strides=2, padding='same', use_bias=False), BatchNormalization(), ReLU(), AvgPool2D(pool_size=3, strides=2, padding='same') ]) self.layer1 = self._make_layer(block, 64, num_blocks[0], strides=1) self.layer2 = self._make_layer(block, 128, num_blocks[1], strides=2) self.layer3 = self._make_layer(block, 256, num_blocks[2], strides=2) self.layer4 = self._make_layer(block, 512, num_blocks[3], strides=2) self.avgpool = AvgPool2D(pool_size=7, strides=1) self.flatten = Flatten() self.fc = Dense(num_classes, activation='softmax') def _make_layer(self, block, out_channels, num_blocks, strides): strides_list = [strides] + [1] * (num_blocks - 1) layers = keras.Sequential() for stride in strides_list: layers.add(block(self.in_channels, out_channels, stride)) self.in_channels = out_channels return layers def call(self, inputs): x = self.conv1(inputs) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = self.flatten(x) x = self.fc(x) return x ``` 可以看到,ResNet-50的实现比较复杂,包含多个残差模块和全连接层。其中,`_make_layer`方法用来构建多个残差模块,`call`方法用来定义整个网络结构。最后可以用以下代码来进行模型的训练和测试: ``` model = ResNet(ResidualBlock, [3, 4, 6, 3], num_classes=10) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) (x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data() x_train = x_train.astype('float32') / 255.0 x_test = x_test.astype('float32') / 255.0 y_train = keras.utils.to_categorical(y_train, num_classes=10) y_test = keras.utils.to_categorical(y_test, num_classes=10) model.fit(x_train, y_train, batch_size=64, epochs=10, validation_data=(x_test, y_test)) ``` 这里的数据集是CIFAR-10,数据预处理和训练过程略。运行以上代码,就可以得到一个训练好的ResNet-50模型。 ### 回答3: ResNet50是Residual Network的一种经典架构,它能有效缓解深度卷积神经网络的梯度弥散问题,使得网络能够更深,参数更多,最终达到更好的性能。今天我们将介绍如何用TensorFlow 2.0实现ResNet50。 首先,我们导入相关的包: ``` import tensorflow as tf from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, BatchNormalization, GlobalAveragePooling2D, Dropout, Flatten, Input, add from tensorflow.keras.models import Model ``` 然后我们定义ResNet50的基础单元,也叫作残差块。这个残差块由两层卷积、批归一化、Relu激活函数和一个恒等映射构成。就像这样: ``` def residual_block(inputs, filters, kernel_size, strides): shortcut = inputs x = Conv2D(filters[0], kernel_size=1, strides=strides, padding='valid')(inputs) x = BatchNormalization()(x) x = tf.keras.layers.ReLU()(x) x = Conv2D(filters[1], kernel_size=kernel_size, strides=1, padding='same')(x) x = BatchNormalization()(x) x = tf.keras.layers.ReLU()(x) x = Conv2D(filters[2], kernel_size=1, strides=1, padding='valid')(x) x = BatchNormalization()(x) if strides != 1 or inputs.shape[-1] != filters[2]: shortcut = Conv2D(filters[2], kernel_size=1, strides=strides, padding='valid')(shortcut) shortcut = BatchNormalization()(shortcut) x = add([x, shortcut]) x = tf.keras.layers.ReLU()(x) return x ``` 接下来定义ResNet50的完整模型。整个模型由7个卷积层、4个残差块和一个全连接层构成。就像这样: ``` def ResNet50(input_shape=(224, 224, 3)): inputs = Input(input_shape) x = Conv2D(64, kernel_size=7, strides=2, padding='same')(inputs) x = BatchNormalization()(x) x = tf.keras.layers.ReLU()(x) x = MaxPooling2D(pool_size=3, strides=2, padding='same')(x) x = residual_block(x, [64, 64, 256], kernel_size=3, strides=1) x = residual_block(x, [64, 64, 256], kernel_size=3, strides=1) x = residual_block(x, [64, 64, 256], kernel_size=3, strides=1) x = residual_block(x, [128, 128, 512], kernel_size=3, strides=2) x = residual_block(x, [128, 128, 512], kernel_size=3, strides=1) x = residual_block(x, [128, 128, 512], kernel_size=3, strides=1) x = residual_block(x, [128, 128, 512], kernel_size=3, strides=1) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=2) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=1) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=1) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=1) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=1) x = residual_block(x, [256, 256, 1024], kernel_size=3, strides=1) x = residual_block(x, [512, 512, 2048], kernel_size=3, strides=2) x = residual_block(x, [512, 512, 2048], kernel_size=3, strides=1) x = residual_block(x, [512, 512, 2048], kernel_size=3, strides=1) x = GlobalAveragePooling2D()(x) x = Dense(1000, activation='softmax')(x) model = Model(inputs=inputs, outputs=x) return model ``` 最后我们构建一个ResNet50模型,并使用ImageDataGenerator读取数据集和fit方法训练模型: ``` datagenerator_train = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255.0) datagenerator_test = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255.0) train_generator = datagenerator_train.flow_from_directory('./data/train', target_size=(224,224), batch_size=32, class_mode='categorical') valid_generator = datagenerator_test.flow_from_directory('./data/valid', target_size=(224,224), batch_size=32, class_mode='categorical') model = ResNet50() model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) history = model.fit(train_generator, epochs=10, validation_data=valid_generator) ``` 现在,你已经成功地使用TensorFlow 2.0实现ResNet50模型,并使用ImageDataGenerator读取数据集和fit方法训练了模型,你可以拿到数据集进行测试并进行更多的调整,期望能够取得优秀的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值