深度学习----第J1周:ResNet50算法实战

news2024/9/24 11:31:42

深度学习----第J1周:ResNet50算法实战

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • ** 参考文章:Pytorch实战 | 第P5周:运动鞋识别**
  • 🍖 原作者:K同学啊|接辅导、项目定制

文章目录

  • 深度学习----第J1周:ResNet50算法实战
  • 前言
  • 一、残差网络介绍
  • 二、前期工作
    • 1.导入数据
    • 2.加载数据
    • 3.可视化数据
  • 三、ResNet-50网络模型
  • 四、构建ResNet-50网络模型
    • 1.tensorflow 代码
    • 2.pytorch 代码(自己实现)
  • 五、模型评估
  • 六、全部代码(tensorflow框架)


前言

  • 经过本周的练习知道ResNet50基本的网络结构,了解残差网络基本结构,自己也用pytorch框架进行实现了ResNet50网络结构代码编写,同时也掌握tensorflow框架下ResNet50网络结构代码编写。
  • 对残差网络这部分内容进行重新梳理,以及数据集有关操作,自己网络结构编写代码时,出现的代码错误自己很容易就能找到并改正。

一、残差网络介绍

  • 其实残差网络我们可以看一个最基本(小)的一个结构图。
  • 其实最后残差连接进行 add 操作时,会发现特征的宽和高是一致, 而通道数可以不一致 在这里插入图片描述

二、前期工作

1.导入数据

  • 其中图片总数为 565
import tensorflow as tf
import matplotlib.pyplot as plt
import os, PIL, pathlib,glob
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.layers import Input, Activation, BatchNormalization, Flatten
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling2D
from tensorflow.keras import Model

gpus = tf.config.list_physical_devices("GPU")

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)
    tf.config.set_visible_devices([gpus[0]], "GPU")


data_dir = './bird/bird_photos'
data_dir = pathlib.Path(data_dir)

image_count = len(list(data_dir.glob('*/*')))
print("图片总数为: ", image_count)

2.加载数据

batch_size = 8
img_height = 224
img_width = 224

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size
)

val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size
)

class_names = train_ds.class_names
print(class_names)

3.可视化数据

plt.figure(figsize=(10, 5))

for images, labels in train_ds.take(1):
    for i in range(8):

        ax = plt.subplot(2, 4, i+1)

        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])

        plt.axis("off")

在这里插入图片描述

三、ResNet-50网络模型

  • ResNet-50 有两个基本的模块, 分别为Conv Block 和 Identity Block
    在这里插入图片描述
  • 对模型网络结构进行绘制
    在这里插入图片描述

四、构建ResNet-50网络模型

1.tensorflow 代码

# 构建resnet-50网络中的残差模块
def identity_block(input_tensor, kernel_size, filters, stage, block):

    filters_1, filters_2, filters_3 = filters

    name_base = str(stage) + block + '_identity_block_'

    x = Conv2D(filters_1, (1, 1), name=name_base+'conv1')(input_tensor)
    x = BatchNormalization(name=name_base + 'bn1')(x)
    x = Activation('relu', name=name_base + 'relu1')(x)

    x = Conv2D(filters_2, kernel_size, padding='same', name=name_base + 'conv2')(x)
    x = BatchNormalization(name=name_base + 'bn2')(x)
    x = Activation('relu', name=name_base + 'relu2')(x)

    x = Conv2D(filters_3, (1, 1), name=name_base + 'conv3')(x)
    x = BatchNormalization(name=name_base + 'bn3')(x)

    x = layers.add([x, input_tensor], name=name_base + 'add')
    x = Activation('relu', name=name_base + 'relu4')(x)

    return x


# 卷积模块
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):

    filters_1, filters_2, filters_3 = filters

    res_name_base = str(stage) + block + '_conv_block_res_'
    name_base = str(stage) + block + '_conv_block_'

    x = Conv2D(filters_1, (1, 1), strides=strides, name=name_base + 'conv1')(input_tensor)
    x = BatchNormalization(name=name_base + 'bn1')(x)
    x = Activation('relu', name=name_base + 'relu1')(x)

    x = Conv2D(filters_2, kernel_size, padding='same', name=name_base + 'conv2')(x)
    x = BatchNormalization(name=name_base + 'bn2')(x)
    x = Activation('relu', name=name_base + 'relu2')(x)

    x = Conv2D(filters_3, (1, 1), name=name_base + 'conv3')(x)
    x = BatchNormalization(name=name_base + 'bn3')(x)

    shortcut = Conv2D(filters_3, (1, 1), strides=strides, name=res_name_base + 'conv')(input_tensor)
    shortcut = BatchNormalization(name=res_name_base + 'bn')(shortcut)

    x = layers.add([x, shortcut], name=name_base + 'add')
    x = Activation('relu', name=name_base + 'relu4')(x)

    return x


def ResNet50(input_shape=[224, 224, 3], classes=1000):

    img_input = Input(shape=input_shape)
    x = ZeroPadding2D((3, 3))(img_input)

    x = Conv2D(64, (7, 7), strides=(2, 2), name='conv1')(x)
    x = BatchNormalization(name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), 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')

    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')

    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')

    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')

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

    x = Flatten()(x)
    x = Dense(classes, activation='softmax', name='fc1000')(x)

    model = Model(img_input, x, name='resnet50')

    # 加载预训练模型
    model.load_weights('./bird/resnet50_weights_tf_dim_ordering_tf_kernels.h5')

    return model


model = ResNet50()
print(model.summary())

2.pytorch 代码(自己实现)

class ResBlock_1(nn.Module):

    def __init__(self, down_sample, in_channels, min_channels, out_channels):
        super(ResBlock_1, self).__init__()

        self.down_sample = down_sample

        self.conv_1 = nn.Sequential(
            nn.Conv2d(in_channels, min_channels, 1, 1, 0),
            nn.BatchNorm2d(min_channels),
            nn.ReLU(),

            nn.Conv2d(min_channels, min_channels, 3, 1, 1),
            nn.BatchNorm2d(min_channels),
            nn.ReLU(),

            nn.Conv2d(min_channels, out_channels, 3, 1, 1),
            nn.BatchNorm2d(out_channels),
            nn.ReLU()

        )

        self.shortcut_conv = nn.Conv2d(in_channels, out_channels, 1, 1, 0)
        self.shortcut_bn = nn.BatchNorm2d(out_channels)

        self.relu = nn.ReLU()

    def forward(self, x):
        if self.down_sample is True:
            shortcut = self.shortcut_bn(self.shortcut_conv(x))
            x = self.conv_1(x)
            x = x + shortcut
            x = self.relu(x)

        else:
            shortcut = x
            x = self.conv_1(x)
            x = x + shortcut
            x = self.relu(x)

        return x

class ResBlock_2(nn.Module):

    def __init__(self, down_sample, in_channels, min_channels, out_channels):
        super(ResBlock_2, self).__init__()

        self.down_sample = down_sample

        if self.down_sample is True:
            s = 2
        else:
            s = 1
        self.conv_2 = nn.Sequential(
            nn.Conv2d(in_channels, min_channels, 1, 1, 0),
            nn.BatchNorm2d(min_channels),
            nn.ReLU(),

            nn.Conv2d(min_channels, min_channels, 3, s, 1),
            nn.BatchNorm2d(min_channels),
            nn.ReLU(),

            nn.Conv2d(min_channels, out_channels, 1, 1, 0),
            nn.BatchNorm2d(out_channels),
            nn.ReLU()
        )

        self.shortcut_conv = nn.Conv2d(in_channels, out_channels, 1, 2, 0)
        self.shortcut_bn = nn.BatchNorm2d(out_channels)

        self.relu = nn.ReLU()

    def forward(self, x):
        if self.down_sample is True:
            shortcut = self.shortcut_bn(self.shortcut_conv(x))
            x = self.conv_2(x)
            x = x + shortcut
            x = self.relu(x)

        else:
            shortcut = x
            x = self.conv_2(x)
            x = x + shortcut
            x = self.relu(x)

        return x


class Resnet_50(nn.Module):
    """
    搭建一个简单的残差网络: RESNET 50
    输入: 224*224*3
    输出: 1000类
    """
    def __init__(self):
        super(Resnet_50, self).__init__()

        # Layer 0
        self.layer_0 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=7, stride=2, padding=3),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        )

        self.layer_1 = nn.Sequential(
            # 需要下采样
            ResBlock_1(True, 64, 64, 256),

            # 无需下采样
            ResBlock_1(False, 256, 64, 256),

            # 无需下采样
            ResBlock_1(False, 256, 64, 256),
        )

        self.layer_2 = nn.Sequential(
            # 需要下采样
            ResBlock_2(True, 256, 128, 512),

            # 无需下采样
            ResBlock_2(False, 512, 128, 512),

            # 无需下采样
            ResBlock_2(False, 512, 128, 512),

            # 无需下采样
            ResBlock_2(False, 512, 128, 512),
        )

        self.layer_3 = nn.Sequential(
            # 需要下采样
            ResBlock_2(True, 512, 256, 1024),

            # 无需下采样
            ResBlock_2(False, 1024, 256, 1024),

            # 无需下采样
            ResBlock_2(False, 1024, 256, 1024),

            # 无需下采样
            ResBlock_2(False, 1024, 256, 1024),

            # 无需下采样
            ResBlock_2(False, 1024, 256, 1024),

            # 无需下采样
            ResBlock_2(False, 1024, 256, 1024),
        )

        self.layer_4 = nn.Sequential(
            # 需要下采样
            ResBlock_2(True, 1024, 512, 2048),

            # 无需下采样
            ResBlock_2(False, 2048, 512, 2048),

            # 无需下采样
            ResBlock_2(False, 2048, 512, 2048),

        )

        # AdaptiveAvgPool2d
        self.app = nn.AdaptiveAvgPool2d(1)

        self.flatten = nn.Flatten()

        self.linear = nn.Linear(2048, 1000)

    def forward(self, x):

        x = self.layer_0(x)
        x = self.layer_1(x)
        x = self.layer_2(x)
        x = self.layer_3(x)
        x = self.layer_4(x)
        x = self.app(x)
        x = self.flatten(x)
        x = self.linear(x)

        return x


五、模型评估

在这里插入图片描述

六、全部代码(tensorflow框架)

import tensorflow as tf
import matplotlib.pyplot as plt
import os, PIL, pathlib,glob
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.layers import Input, Activation, BatchNormalization, Flatten
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling2D
from tensorflow.keras import Model

gpus = tf.config.list_physical_devices("GPU")

if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)
    tf.config.set_visible_devices([gpus[0]], "GPU")


data_dir = './bird/bird_photos'
data_dir = pathlib.Path(data_dir)

image_count = len(list(data_dir.glob('*/*')))
print("图片总数为: ", image_count)

# 加载数据
batch_size = 8
img_height = 224
img_width = 224

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size
)

val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size
)

class_names = train_ds.class_names
print(class_names)

plt.figure(figsize=(10, 5))

for images, labels in train_ds.take(1):
    for i in range(8):

        ax = plt.subplot(2, 4, i+1)

        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])

        plt.axis("off")


# 再次检查数据
for image_batch, labels_batch in train_ds:

    print(image_batch.shape)
    print(labels_batch.shape)
    break


# 配置数据集
AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)


# 构建resnet-50网络中的残差模块
def identity_block(input_tensor, kernel_size, filters, stage, block):

    filters_1, filters_2, filters_3 = filters

    name_base = str(stage) + block + '_identity_block_'

    x = Conv2D(filters_1, (1, 1), name=name_base+'conv1')(input_tensor)
    x = BatchNormalization(name=name_base + 'bn1')(x)
    x = Activation('relu', name=name_base + 'relu1')(x)

    x = Conv2D(filters_2, kernel_size, padding='same', name=name_base + 'conv2')(x)
    x = BatchNormalization(name=name_base + 'bn2')(x)
    x = Activation('relu', name=name_base + 'relu2')(x)

    x = Conv2D(filters_3, (1, 1), name=name_base + 'conv3')(x)
    x = BatchNormalization(name=name_base + 'bn3')(x)

    x = layers.add([x, input_tensor], name=name_base + 'add')
    x = Activation('relu', name=name_base + 'relu4')(x)

    return x


# 卷积模块
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):

    filters_1, filters_2, filters_3 = filters

    res_name_base = str(stage) + block + '_conv_block_res_'
    name_base = str(stage) + block + '_conv_block_'

    x = Conv2D(filters_1, (1, 1), strides=strides, name=name_base + 'conv1')(input_tensor)
    x = BatchNormalization(name=name_base + 'bn1')(x)
    x = Activation('relu', name=name_base + 'relu1')(x)

    x = Conv2D(filters_2, kernel_size, padding='same', name=name_base + 'conv2')(x)
    x = BatchNormalization(name=name_base + 'bn2')(x)
    x = Activation('relu', name=name_base + 'relu2')(x)

    x = Conv2D(filters_3, (1, 1), name=name_base + 'conv3')(x)
    x = BatchNormalization(name=name_base + 'bn3')(x)

    shortcut = Conv2D(filters_3, (1, 1), strides=strides, name=res_name_base + 'conv')(input_tensor)
    shortcut = BatchNormalization(name=res_name_base + 'bn')(shortcut)

    x = layers.add([x, shortcut], name=name_base + 'add')
    x = Activation('relu', name=name_base + 'relu4')(x)

    return x


def ResNet50(input_shape=[224, 224, 3], classes=1000):

    img_input = Input(shape=input_shape)
    x = ZeroPadding2D((3, 3))(img_input)

    x = Conv2D(64, (7, 7), strides=(2, 2), name='conv1')(x)
    x = BatchNormalization(name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), 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')

    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')

    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')

    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')

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

    x = Flatten()(x)
    x = Dense(classes, activation='softmax', name='fc1000')(x)

    model = Model(img_input, x, name='resnet50')

    # 加载预训练模型
    model.load_weights('./bird/resnet50_weights_tf_dim_ordering_tf_kernels.h5')

    return model


model = ResNet50()
print(model.summary())


# 编译
opt = tf.keras.optimizers.Adam(learning_rate=1e-7)

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy']
              )


# 模型训练
epochs = 10

history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=epochs
)


acc = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs_range = range(epochs)

plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')


plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.show()






本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/672692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch 分词器

前奏 es的chinese、english、standard等分词器对中文分词十分不友好,几乎都是逐字分词,对英文分词比较友好。 在kibana的dev tools中测试分词: POST /_analyze {"analyzer": "standard","text": "你太…

chatgpt赋能python:Python文件导出方法详解

Python文件导出方法详解 Python是一种高级编程语言,广泛应用于各种数据科学、人工智能、Web开发等领域。在Python开发中,我们需要将处理好的数据与结果输出为合适的格式,文件导出是常见的输出方式之一。在本文中,我们将详细介绍P…

【C++篇】C++的输入和输出

友情链接:C/C系列系统学习目录 知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的…

chatgpt赋能python:Python整人代码大全

Python整人代码大全 作为一名有10年Python编程经验的工程师,我深知Python这门编程语言广泛应用于各种领域,包括网络编程、数据分析、人工智能等等。然而,Python同样也有着一些有趣的应用,比如用来整人。 在这篇文章中&#xff0…

[设计模式] OOP六大原则

文章目录 前言1、六大原则1.1、单一职责原则1.2、开闭原则1.3、里氏替换原则1.4、依赖倒置原则1.5、接口隔离原则1.6、迪米特原则 前言 Object Oriented Programming 面向对象编程 1、六大原则 1.1、单一职责原则 就一个类而言,应该仅有一个引起它变化的原因。应…

MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 -- 下

MIT 6.S081 教材第四章内容 -- 下 引言从内核空间陷入页面错误异常Page Fault BasicsLazy page allocationZero Fill On DemandCopy On Write ForkDemand PagingMemory Mapped Files 真实世界 引言 MIT 6.S081 2020 操作系统 本文为MIT 6.S081课程第四章教材内容翻译加整理。…

机器人工程创新类课程补充说明-2023-

内容仅供参考,不严谨。 案例: 在f1tenth仿真中如何实现更快速的跑圈-曲线分析篇 所有课程其实主动权永远都掌握在学生手中,愿意学的会多花时间自主研究(主动学习),不愿意的就会用一些独特手段应付&#xf…

硬件入门之什么是电感

硬件入门之什么是电感 文章目录 硬件入门之什么是电感一、电感是什么?电感在电路中的作用:通直流隔交流,防止电流突变,储能。 二、实际应用场景常见电容:1.贴片电感(无正负极之分)2、变压器&…

第六章 MobileNetv1网络详解

系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网络详解 第七章 MobileNetv2网络详解 第八章 MobileNetv3网络详解 第九章 ShuffleNetv1网络详解 第十章…

chatgpt赋能python:Python文件怎么改名:简单易用的方法

Python文件怎么改名:简单易用的方法 在Python开发中,文件的重命名是一个经常用到的操作。无论是更改文件名还是批量重命名,在Python中都可以非常轻松地实现。本文将介绍三种不同的方法来改变Python文件的名称。 方法一:使用os模…

哔哩下载姬 - DownKyi

这款开源工具小编自己还是蛮喜欢的,有兴趣的小伙伴可以体验学习下。 一、简单介绍 Downkyi是一个极其便捷的开源工具,专为Bilibili视频下载而设计。它拥有一个简洁、直观的界面,操作逻辑流畅无比。Downkyi能够下载几乎所有B站视频&#xff0…

11.创建CentOS虚拟机

创建不同类型的实例虚拟机,我们是需要根据需求来准备镜像上传到glance,注意 ISO 镜像上传上去是没法直接使用的,需要将 ISO 镜像转变成qcow2磁盘文件,然后上传磁盘文件,就可以创建云主机。 官方镜像仓库地址&#xff1…

FBM237 RH914XS而且控制部件采用冗余容错技术,运行可靠性提高

​ FBM237 RH914XS而且控制部件采用冗余容错技术,运行可靠性提高 FBM237 RH914XS而且控制部件采用冗余容错技术,运行可靠性提高 概述 dcs系统与其他计算机设备是由电子元件和大规模集成电路构成,结构紧密,而且控制部件采用冗余容错技术,运行可靠性提高。…

人工智能气象一:深度学习预测浅水方程模式

查看原文>>>基于Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用能力 目录 专题一、Python软件的安装及入门 专题二、气象常用科学计算库 专题三、气象海洋常用可视化库 专题四、爬虫和气象海洋数据 专题五、气象海洋常用插值方法 专题六、机器…

AIGC下的CV多模态原理解析:从CLIP/BLIP到stable diffusion/Midjourney、GPT4

前言 终于开写本CV多模态系列的核心主题:stable diffusion相关的了,为何执着于想写这个stable diffusion呢,源于三点 去年stable diffusion和midjourney很火的时候,就想写,因为经常被刷屏,但那会时间错不…

RabbitMQ入门案例之Work模式

前言 本文章将介绍RabbitMQ的Work模式,其中这个模式又细分为轮询分发和公平分发,本文将会用Java代码结合RabbitMQ的web管理界面进行实操演示。 官网文档地址:https://rabbitmq.com/getstarted.html 什么是Work模式 RabbitMQ的Work模式是一种…

ActiveX控件打包成Cab置于网页中自动下载安装

[背景] 做过ActiveX控件的朋友都知道,要想把自己做的ActiveX控件功能放在自己的网页上使用,那么用户在客户端就必须进行本地的注册,也就是说用户得首先要把该ActiveX控件(test.ocx)放在本机的%system%/system32下,然后运行DOS工具…

Linux:第四章课后习题及答案

第四章 目录和文件管理 Q1:Linux系统中有哪些文件类型 Linux文件类型常见的有:普通文件、目录 文件、设备文件(字符设备文件和块设备 文件)、管道文件和符号链接文件等。普通文件 用“ls -lh”命令查看某个文件的属性&#xff0…

Docker 部署 分布式搜索引擎 Elastic Search

文章目录 ⛄引言一、使用Elastic Search 的好处二、部署ES⛅部署kibana⚡部署分词器 三、词典扩展与停用⛅扩展词典⚡停用词典 ⛵小结 ⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮…

【C++篇】模板

友情链接:C/C系列系统学习目录 知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的…