mmsegmentation 训练Binary segmentation

news2024/11/26 9:47:49

1.一天最无聊的事从搭环境开始

1.conda create -n swin python=3.7 
2.conda activate swin
3.conda install pytorch==1.7.0 torchvision==0.8.0 torchaudio==0.7.0 cudatoolkit=11.0
4.pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu110/torch1.7.0/index.html
5.pip install mmseg
#需要注意的是pytorch版本、cuda版本与mmcv版本需搭配,否则会出错。

2.环境搭好下个官方的模型测试一下,测试脚本如下。

from mmseg.apis import inference_segmentor, init_segmentor
import mmcv

config_file = '../configs/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes.py'
checkpoint_file = '../ckpt/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth'

# 通过配置文件和模型权重文件构建模型
model = init_segmentor(config_file, checkpoint_file, device='cuda:0')

# 对单张图片进行推理并展示结果
img = 'demo.png'  # or img = mmcv.imread(img), which will only load it once
result = inference_segmentor(model, img)
# 在新窗口中可视化推理结果
model.show_result(img, result, show=True)
# 或将可视化结果存储在文件中
# 你可以修改 opacity 在(0,1]之间的取值来改变绘制好的分割图的透明度
model.show_result(img, result, out_file='result.jpg', opacity=1)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.至此,可以准备自己的数据集了。数据集自定义

在这里插入图片描述
数据集如上图所示。images下是训练验证时用到的原始图像,annotations下是训练验证时用到的label

4.开始定义自己的数据集

在这里插入图片描述
dataset下新建一个py文件用来处理自己的数据集

# dataset settings
dataset_type = 'MydataDataset'
data_root = 'data/mydata'
img_norm_cfg = dict(
    mean=[35.1826, 35.1826, 35.1826], std=[41.0360, 41.0360, 41.0360], to_rgb=True)
crop_size = (512, 512)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations', reduce_zero_label=False),
    dict(type='Resize', img_scale=(512, 512), ratio_range=(0.5, 2.0)),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_semantic_seg']),
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(512, 512),
        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Normalize', **img_norm_cfg),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img']),
        ])
]
data = dict(
    samples_per_gpu=4, #设置每个GPU的batch_size
    workers_per_gpu=6, #设置每个GPU对应读取线程数
    train=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='images/training',
        ann_dir='annotations/training',
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='images/validation',
        ann_dir='annotations/validation',
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='images/validation',
        ann_dir='annotations/validation',
        pipeline=test_pipeline))

5.mmseg下datasets自定义自己的数据集

在这里插入图片描述

# Copyright (c) OpenMMLab. All rights reserved.
import os.path as osp

from .builder import DATASETS
from .custom import CustomDataset


@DATASETS.register_module()
class MydataDataset(CustomDataset):


    CLASSES = ('background', '你自己的类别')

    PALETTE = [[0, 0, 0], [255, 255, 255]]

    def __init__(self, **kwargs):
        super(MydataDataset, self).__init__(
            img_suffix='.jpg',
            seg_map_suffix='.png',
            reduce_zero_label=False,
            ignore_index=10,
            classes= ('background', '你自己的类别'),
            palette=[[0, 0, 0], [255, 255, 255]],
            **kwargs)
        assert osp.exists(self.img_dir)

6.init.py里引入自己定义的数据集

在这里插入图片描述

# Copyright (c) OpenMMLab. All rights reserved.
from .ade import ADE20KDataset
from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset
from .chase_db1 import ChaseDB1Dataset
from .cityscapes import CityscapesDataset
from .coco_stuff import COCOStuffDataset
from .custom import CustomDataset
from .dark_zurich import DarkZurichDataset
from .dataset_wrappers import (ConcatDataset, MultiImageMixDataset,
                               RepeatDataset)
from .drive import DRIVEDataset
from .face import FaceOccludedDataset
from .hrf import HRFDataset
from .isaid import iSAIDDataset
from .isprs import ISPRSDataset
from .loveda import LoveDADataset
from .night_driving import NightDrivingDataset
from .pascal_context import PascalContextDataset, PascalContextDataset59
from .potsdam import PotsdamDataset
from .stare import STAREDataset
from .voc import PascalVOCDataset
from .mydata import MydataDataset

__all__ = [
    'CustomDataset', 'build_dataloader', 'ConcatDataset', 'RepeatDataset',
    'DATASETS', 'build_dataset', 'PIPELINES', 'CityscapesDataset',
    'PascalVOCDataset', 'ADE20KDataset', 'PascalContextDataset',
    'PascalContextDataset59', 'ChaseDB1Dataset', 'DRIVEDataset', 'HRFDataset',
    'STAREDataset', 'DarkZurichDataset', 'NightDrivingDataset',
    'COCOStuffDataset', 'LoveDADataset', 'MultiImageMixDataset',
    'iSAIDDataset', 'ISPRSDataset', 'PotsdamDataset', 'FaceOccludedDataset','MydataDataset'
]

7.定义evaluation里自己的数据集

def mydata_classes():
    return ['background','你自己的数据集']
def mydata_palette():
   
    return [[0, 0, 0], [255, 255, 255]]

8.由于选的时ocrnet作为自己的baseline,需要去config下选一个你自己的喜欢的模型。修改num_classes及加载上自己的数据预处理模块。

_base_ = [
    '../_base_/models/ocrnet_hr18.py', '../_base_/datasets/mydata.py',
    '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py'
]
norm_cfg = dict(type='SyncBN', requires_grad=True)
model = dict(decode_head=[
    dict(
        type='FCNHead',
        in_channels=[18, 36, 72, 144],
        channels=sum([18, 36, 72, 144]),
        in_index=(0, 1, 2, 3),
        input_transform='resize_concat',
        kernel_size=1,
        num_convs=1,
        concat_input=False,

        dropout_ratio=-1,
        num_classes=2,
        #out_channels=2,
        norm_cfg=norm_cfg,
        align_corners=False,
        loss_decode=dict(
            type='DiceLoss', use_sigmoid=False, loss_weight=0.4)),
    dict(
        type='OCRHead',
        in_channels=[18, 36, 72, 144],
        in_index=(0, 1, 2, 3),
        input_transform='resize_concat',
        channels=512,
        ocr_channels=256,
        dropout_ratio=-1,
        num_classes=2,
        #out_channels=2,
        norm_cfg=norm_cfg,
        align_corners=False,
        loss_decode=dict(
            type='DiceLoss', use_sigmoid=False, loss_weight=1.0)),
])

9.这个时候可以开始训练了,但是由bug。

在这里插入图片描述

10.bug排查,因为mmseg分割单个类别将背景赋值为0前景赋值为1,需要对loading里的代码进行修改:gt_semantic_seg[gt_semantic_seg_copy == old_id*255] = new_id

在这里插入图片描述

# Copyright (c) OpenMMLab. All rights reserved.
import os.path as osp

import mmcv
import numpy as np

from ..builder import PIPELINES


@PIPELINES.register_module()
class LoadImageFromFile(object):
    """Load an image from file.

    Required keys are "img_prefix" and "img_info" (a dict that must contain the
    key "filename"). Added or updated keys are "filename", "img", "img_shape",
    "ori_shape" (same as `img_shape`), "pad_shape" (same as `img_shape`),
    "scale_factor" (1.0) and "img_norm_cfg" (means=0 and stds=1).

    Args:
        to_float32 (bool): Whether to convert the loaded image to a float32
            numpy array. If set to False, the loaded image is an uint8 array.
            Defaults to False.
        color_type (str): The flag argument for :func:`mmcv.imfrombytes`.
            Defaults to 'color'.
        file_client_args (dict): Arguments to instantiate a FileClient.
            See :class:`mmcv.fileio.FileClient` for details.
            Defaults to ``dict(backend='disk')``.
        imdecode_backend (str): Backend for :func:`mmcv.imdecode`. Default:
            'cv2'
    """

    def __init__(self,
                 to_float32=False,
                 color_type='color',
                 file_client_args=dict(backend='disk'),
                 imdecode_backend='cv2'):
        self.to_float32 = to_float32
        self.color_type = color_type
        self.file_client_args = file_client_args.copy()
        self.file_client = None
        self.imdecode_backend = imdecode_backend

    def __call__(self, results):
        """Call functions to load image and get image meta information.

        Args:
            results (dict): Result dict from :obj:`mmseg.CustomDataset`.

        Returns:
            dict: The dict contains loaded image and meta information.
        """

        if self.file_client is None:
            self.file_client = mmcv.FileClient(**self.file_client_args)

        if results.get('img_prefix') is not None:
            filename = osp.join(results['img_prefix'],
                                results['img_info']['filename'])
        else:
            filename = results['img_info']['filename']
        img_bytes = self.file_client.get(filename)
        img = mmcv.imfrombytes(
            img_bytes, flag=self.color_type, backend=self.imdecode_backend)
        if self.to_float32:
            img = img.astype(np.float32)

        results['filename'] = filename
        results['ori_filename'] = results['img_info']['filename']
        results['img'] = img
        results['img_shape'] = img.shape
        results['ori_shape'] = img.shape
        # Set initial values for default meta_keys
        results['pad_shape'] = img.shape
        results['scale_factor'] = 1.0
        num_channels = 1 if len(img.shape) < 3 else img.shape[2]
        results['img_norm_cfg'] = dict(
            mean=np.zeros(num_channels, dtype=np.float32),
            std=np.ones(num_channels, dtype=np.float32),
            to_rgb=False)
        return results

    def __repr__(self):
        repr_str = self.__class__.__name__
        repr_str += f'(to_float32={self.to_float32},'
        repr_str += f"color_type='{self.color_type}',"
        repr_str += f"imdecode_backend='{self.imdecode_backend}')"
        return repr_str


@PIPELINES.register_module()
class LoadAnnotations(object):
    """Load annotations for semantic segmentation.

    Args:
        reduce_zero_label (bool): Whether reduce all label value by 1.
            Usually used for datasets where 0 is background label.
            Default: False.
        file_client_args (dict): Arguments to instantiate a FileClient.
            See :class:`mmcv.fileio.FileClient` for details.
            Defaults to ``dict(backend='disk')``.
        imdecode_backend (str): Backend for :func:`mmcv.imdecode`. Default:
            'pillow'
    """

    def __init__(self,
                 reduce_zero_label=False,
                 file_client_args=dict(backend='disk'),
                 imdecode_backend='pillow'):
        self.reduce_zero_label = reduce_zero_label
        self.file_client_args = file_client_args.copy()
        self.file_client = None
        self.imdecode_backend = imdecode_backend

    def __call__(self, results):
        """Call function to load multiple types annotations.

        Args:
            results (dict): Result dict from :obj:`mmseg.CustomDataset`.

        Returns:
            dict: The dict contains loaded semantic segmentation annotations.
        """

        if self.file_client is None:
            self.file_client = mmcv.FileClient(**self.file_client_args)

        if results.get('seg_prefix', None) is not None:
            filename = osp.join(results['seg_prefix'],
                                results['ann_info']['seg_map'])
        else:
            filename = results['ann_info']['seg_map']
        img_bytes = self.file_client.get(filename)
        gt_semantic_seg = mmcv.imfrombytes(
            img_bytes, flag='unchanged',
            backend=self.imdecode_backend).squeeze().astype(np.uint8)
        # modify if custom classes
        if results.get('label_map', None) is not None:
            # Add deep copy to solve bug of repeatedly
            # replace `gt_semantic_seg`, which is reported in
            # https://github.com/open-mmlab/mmsegmentation/pull/1445/
            gt_semantic_seg_copy = gt_semantic_seg.copy()
            for old_id, new_id in results['label_map'].items():
                gt_semantic_seg[gt_semantic_seg_copy == old_id*255] = new_id
        # reduce zero_label
        if self.reduce_zero_label:
            # avoid using underflow conversion
            gt_semantic_seg[gt_semantic_seg == 0] = 255
            gt_semantic_seg = gt_semantic_seg - 1
            gt_semantic_seg[gt_semantic_seg == 254] = 255
        results['gt_semantic_seg'] = gt_semantic_seg
        results['seg_fields'].append('gt_semantic_seg')
        return results

    def __repr__(self):
        repr_str = self.__class__.__name__
        repr_str += f'(reduce_zero_label={self.reduce_zero_label},'
        repr_str += f"imdecode_backend='{self.imdecode_backend}')"
        return repr_str

11.此外原始的loss为交叉熵loss,修改为DICE loss,backbone的loss也统一一下

# model settings
norm_cfg = dict(type='SyncBN', requires_grad=True)
model = dict(
    type='CascadeEncoderDecoder',
    num_stages=2,
    pretrained='open-mmlab://msra/hrnetv2_w18',
    backbone=dict(
        type='HRNet',
        norm_cfg=norm_cfg,
        norm_eval=False,
        extra=dict(
            stage1=dict(
                num_modules=1,
                num_branches=1,
                block='BOTTLENECK',
                num_blocks=(4, ),
                num_channels=(64, )),
            stage2=dict(
                num_modules=1,
                num_branches=2,
                block='BASIC',
                num_blocks=(4, 4),
                num_channels=(18, 36)),
            stage3=dict(
                num_modules=4,
                num_branches=3,
                block='BASIC',
                num_blocks=(4, 4, 4),
                num_channels=(18, 36, 72)),
            stage4=dict(
                num_modules=3,
                num_branches=4,
                block='BASIC',
                num_blocks=(4, 4, 4, 4),
                num_channels=(18, 36, 72, 144)))),
    decode_head=[
        dict(
            type='FCNHead',
            in_channels=[18, 36, 72, 144],
            channels=sum([18, 36, 72, 144]),
            in_index=(0, 1, 2, 3),
            input_transform='resize_concat',
            kernel_size=1,
            num_convs=1,
            concat_input=False,
            dropout_ratio=-1,
            num_classes=2,
            norm_cfg=norm_cfg,
            align_corners=False,
            loss_decode=dict(
                type='DiceLoss', use_sigmoid=False, loss_weight=0.4)),
        dict(
            type='OCRHead',
            in_channels=[18, 36, 72, 144],
            in_index=(0, 1, 2, 3),
            input_transform='resize_concat',
            channels=512,
            ocr_channels=256,
            dropout_ratio=-1,
            num_classes=2,
            norm_cfg=norm_cfg,
            align_corners=False,
            loss_decode=dict(
                type='DiceLoss', use_sigmoid=False, loss_weight=1.0)),
    ],
    # model training and testing settings
    train_cfg=dict(),
    test_cfg=dict(mode='whole'))

在这里插入图片描述
至此,正常训练。iou acc不会出现异常情况

12,测试脚本测试一下

from mmseg.apis import inference_segmentor, init_segmentor
import mmcv
import cv2
from PIL import Image
import numpy as  np


config_file = '../work_dirs/ocrnet_hr18_512x512_80k_ade20k_mydata_baseline/ocrnet_hr18_512x512_80k_ade20k.py'
checkpoint_file = '../work_dirs/ocrnet_hr18_512x512_80k_ade20k_mydata_baseline/latest.pth'

# 通过配置文件和模型权重文件构建模型
model = init_segmentor(config_file, checkpoint_file, device='cuda:0')

# #对单张图片进行推理并展示结果

img = '17.jpg'  # or img = mmcv.imread(img), which will only load it once
#img=img.resize(img,(1000,800))

#打印输入图像通道数
# img=Image.open(img)
# print(len(img.split()))
# imageSize=img.size
# w=img.width
# h=img.height
# f=img.format
#
# print(imageSize)
# print(w,h,f)
result = inference_segmentor(model, img)
print(result)

#np.savetxt(r'result.txt',result)
# 在新窗口中可视化推理结果
model.show_result(img, result, show=True)

print(model.show_result)
# 或将可视化结果存储在文件中
# 可以修改 opacity 在(0,1]之间的取值来改变绘制好的分割图的透明度
model.show_result(img, result, out_file='result17_0.jpg', opacity=1)



#对视频进行推理并展示结果
# video = mmcv.VideoReader('test.avi')
# for frame in video:
#    result = inference_segmentor(model, frame)
#    model.show_result(frame, result, wait_time=1)

效果很好,私人数据这个地方就不展示了。

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

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

相关文章

Keil + STM32学习嵌入式数据结构-01

视频链接 初识数据结构&#xff0c;十天搞定嵌入式数据结构_哔哩哔哩_bilibili 课程目的 学会嵌入式经常使用的数据结构 具备基础知识 具有C语言基础&#xff08;结构体、指针、内存&#xff08;malloc)&#xff09; 具有数据结构的基础知识&#xff0c;因此提及到的基础…

Android 深入系统完全讲解(8)

2 Smali 调试 Smali 是安卓 Apk 反编译出来的格式&#xff0c;类似于我们 PC 上面的汇编语言。语法可以参考这个文 章&#xff1a;https://blog.csdn.net/yuanguozhengjust/article/details/80493963 PC 上的反编译调试工具用 OD 和 IDA&#xff08;这个也可以调试 Android &…

Java 调用 扫描仪的技术该如何选择?

文章目录Java 调用 扫描仪的技术该如何选择?详细介绍;&#xff08;1&#xff09;TWAIN&#xff08;2&#xff09;Kodakimg&#xff08;3&#xff09;Dynamic TWAIN ActiveX&#xff08;4&#xff09;WIA&#xff08;用于桌面应用程序&#xff09;开发应用程序&#xff0c;您可…

计算机组成原理习题一

计算机组成原理习题一 文章目录计算机组成原理习题一题目答案题目 1.某数的IEEE单精度浮点数存储形式为C1F00000H&#xff0c;则其所表示的十进制数真值是多少&#xff1f;要求写出详细求解过程以及最终结果。 2.求出数据10010100110的海明码&#xff0c;可检/纠错一位错&…

【实战篇】40 # 如何实现3D地球可视化?

说明 【跟月影学可视化】学习笔记。 如何实现一个 3D 地球 学习笔记源码实现&#xff1a;https://github.com/kaimo313/visual-learning-demo 整体实现效果如下&#xff1a; 1、绘制一个 3D 球体 <!DOCTYPE html> <html lang"en"><head><m…

五、数据导入与基本的 SELECT 语句

文章目录一、数据导入指令二、基本查询语句2.1 SELECT ...2.2 使用 SELECT 语句查询一个数据表2.3 查询表中的一列或多列三、单表查询3.1 用 DISTINCT 关键字去除结果中的重复行3.2 使用 AS 设置别名3.3 着重号3.4 运算符3.4.1 算术运算符3.4.2 比较运算符3.4.3 逻辑运算符3.4.…

k8s之Deployment

写在前面 本文一起看下Deployment API对象&#xff0c;该对象的作用是保证POD的高可用&#xff0c;即保证POD的可用数量一直维持在某个期望状态中&#xff0c;比如期望状态是有3个POD&#xff0c;当有一个POD意外终止时&#xff0c;则会自动再启动一个新POD&#xff0c;所以De…

Makefile 如何构建Go项目

前言 &#x1f4da; 请问你是如何打包Go语言开发的项目呢&#xff1f; 是直接命令行输入&#xff1f; go build . 开发调试时&#xff1f; go run main.go 但是我们看到开源的Go语言项目运行时是&#xff1a; make build || make install 我们打包运行的这个过程&#xff0…

Mask RCNN网络源码解读(Ⅵ) --- Mask分支及Loss计算

目录 0.先决知识 1.简介 2.mask_rcnn.py解析 2.1 初始化函数 2.2 MaskRCNNHeads类 2.3 MaskRCNNPredictor类 3.RoIHeads类解析 3.1 正向传播过程 3.2 mask部分损失 3.3 maskrcnn_inference 0.先决知识 学习此篇博客之前&#xff0c;读者应有&#xff1a; ①一定的p…

MySQL常用命令 (这些命令专属于MySQL 不属于标准SQL语句)

1、查看MySQL版本 &#xff1a;select version(); ​​​​​​​ ​​​​​​​ ​​​​​​​ 2、创建数据库 &#xff1a;create database 数据库名称; 3、使用/指定数据库&#xff1a;use 数据库名称; 4、查看当前使用的数据库…

硬件系统工程师宝典(3)-----信号完整性分析是个啥?

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。上篇我们读到硬件电路的概要设计需要考虑的问题&#xff0c;相关的可行性分析可以使开发工作事半功倍。信号完整性分析概述今天我们开始学习在高速电…

上海亚商投顾:两市震荡引分化 汽车产业链获青睐

上海亚商投顾前言&#xff1a;无惧大盘大跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪大小指数今日走势分化&#xff0c;沪指全天弱势震荡&#xff0c;创业板指在权重股助力下&#xff0c;午后一度冲高涨…

靶机测试 0s-hackNos-2笔记

简介靶机地址https://www.vulnhub.com/entry/hacknos-os-hacknos-2,403/#Difficulty : Easy to IntermediateFlag : 2 Flag first user And second rootLearning : Web Application | Enumeration | Password Cracking测试过程信息收集nmap扫描端口nmap -p- -A 192.168.1.103 -…

如何在 Zorin OS 上安装 ONLYOFFICE 桌面编辑器

ONLYOFFICE 桌面应用是一款开源办公套件&#xff0c;包括用于文本文档、电子表格、演示文稿和表单的编辑器。除了离线工作&#xff0c;您还可以将该应用连接到云端进行在线文档协作。这款套件的源代码可在 GitHub 上获得&#xff0c;是根据 AGPL v.3.0 许可。 ONLYOFFICE桌面编…

golang中new与make的区别

new和make new // The new built-in function allocates memory. The first argument // is a type,not a value, and the value returned is a pointer to a // newly // allocated zero value of that type. func new(Type) *Type对于官方是这么解释new的&#xff1a;这个…

(6)go-micro微服务consul配置、注册中心

文章目录一 Consul介绍1. 注册中心Consul基本介绍2.注册中心Consul关键功能3.注册中心Consul两个重要协议二 Consul安装1.使用docker拉取镜像三 Config配置四 Consul代码编写1.设置consul配置中心2.获取consul配置中心的数据3.consul可视化界面数据编写4. main.go代码编写五 最…

微信小程序-页面导航

小程序实现页面导航的两种方式 声明式导航(tabBar 页面&#xff0c;在app.json中配置) 在页面上声明一个<navigator>导航组件通过点击<navigator> 组件实现页面跳转 app.json中 "tabBar": {"list": [{"pagePath": "pages/home…

【胖虎的逆向之路】02——Android整体加壳原理详解实现

【胖虎的逆向之路】(02)——Android整体加壳原理详解&实现 Android Apk的加壳原理流程及详解 文章目录【胖虎的逆向之路】(02)——Android整体加壳原理详解&实现前言一、加壳前的知识储备1. Android 应用的启动流程2. Android 应用的安装3. Android应用的启动流程&…

09-JAVA四种引用类型?

在JDK1.2版之后&#xff0c;Java对引用的概念进行了扩充&#xff0c;将引用分为强引用&#xff08;Strongly Reference&#xff09;、软引用&#xff08;Soft Reference&#xff09;、弱引用&#xff08;Weak Reference&#xff09;和虚引用&#xff08;Phantom Reference&…

使用Deep Q-Network学习如何玩《飞行的小鸟》游戏

目录概述效果需要的依赖如何运行算法原理实验输入处理网络结构训练代码概述 使用DQN实现《飞行的小鸟》游戏&#xff0c;代码可修改扩展为其他游戏&#xff0c;适合学习研究用。 效果 需要的依赖 Python 2.7 or 3 TensorFlow 0.7 pygame OpenCV-Python 如何运行 运行主函数…