国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

YOLOv5網(wǎng)絡結構,訓練策略詳解

這篇具有很好參考價值的文章主要介紹了YOLOv5網(wǎng)絡結構,訓練策略詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

前面已經(jīng)講過了Yolov5模型目標檢測和分類模型訓練流程,這一篇講解一下yolov5模型結構,數(shù)據(jù)增強,以及訓練策略。
官方地址:https://github.com/ultralytics/yolov5

yolov5模型訓練流程:https://blog.csdn.net/qq_45066628/article/details/129470290?spm=1001.2014.3001.5501

Yolov5 (v6.2) 使用自己的數(shù)據(jù)訓練分類模型 基于ONNX TensorRT轉換:https://blog.csdn.net/qq_45066628/article/details/129594154?spm=1001.2014.3001.5501

網(wǎng)絡結構

Yolov5發(fā)布的預訓練模型,包含yolov5l.pt、yolov5l6.pt、yolov5m.pt、yolov5m6.pt、yolov5s.pt、yolov5s6.pt、yolov5x.pt、yolov5x6.pt等。針對不同大小的網(wǎng)絡整體架構(n, s, m, l, x)都是一樣的,只不過會在每個子模塊中采用不同的深度和寬度,分別應對yaml文件中的depth_multiple和width_multiple參數(shù)。下面以yolov5l.yaml繪制的網(wǎng)絡整體結構為例。

YOLOv5網(wǎng)絡結構,訓練策略詳解

網(wǎng)絡結構圖

網(wǎng)絡結構主要由以下幾部分組成:
(1)輸入端:Mosaic數(shù)據(jù)增強、自適應錨框計算、自適應圖片縮放
(2) Backbone: New CSP-Darknet53
(3)Neck: SPPF, New CSP-PAN
(4)輸出端:Head

官方網(wǎng)絡結構圖:
source:https://user-images.githubusercontent.com/31005897/157381276-6e8429f3-c759-4aef-aea8-034438919457.png
YOLOv5網(wǎng)絡結構,訓練策略詳解
v5.x網(wǎng)絡結構:
YOLOv5網(wǎng)絡結構,訓練策略詳解
v6.x網(wǎng)絡結構:
YOLOv5網(wǎng)絡結構,訓練策略詳解
source:https://blog.csdn.net/weixin_43799388/article/details/123271962

可以看出,相比于之前v5.x,最新版的v6.x網(wǎng)絡結構更加精簡(以提高速度和推理性能),主要有以下更新:

  • Conv(k=6, s=2, p=2) 替換Focus,便于導出其他框架(for improved exportability)
  • SPPF代替SPP,并且將SPPF放在主干最后一層(for reduced ops)
  • 主干中的C3層重復次數(shù)從9次減小到6次(for reduced ops)
  • 主干中最后一個C3層引入shortcut

yolov5s.yaml文件內(nèi)容

nc: 80  # number of classes 數(shù)據(jù)集中的類別數(shù)
depth_multiple: 0.33  # model depth multiple  模型層數(shù)因子(用來調整網(wǎng)絡的深度)
width_multiple: 0.50  # layer channel multiple 模型通道數(shù)因子(用來調整網(wǎng)絡的寬度)
# 如何理解這個depth_multiple和width_multiple呢?它決定的是整個模型中的深度(層數(shù))和寬度(通道數(shù)。

anchors: # 表示作用于當前特征圖的Anchor大小為 xxx
# 9個anchor,其中P表示特征圖的層級,P3/8該層特征圖縮放為1/8,是第3層特征
  - [10,13, 16,30, 33,23]  # P3/8, 表示[10,13],[16,30], [33,23]3個anchor
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32


# YOLOv5s v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5s v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

nc是類別數(shù);

depth_multiple表示channel的縮放系數(shù),就是將配置里面的backbone和head部分有關通道的設置,全部乘以該系數(shù)即可;

而width_multiple表示BottleneckCSP模塊的層縮放系數(shù),將所有的BottleneckCSP模塊的number系數(shù)乘上該參數(shù)就可以最終的層個數(shù);如果希望大一點,就把這個數(shù)字改大一點,網(wǎng)絡就會按比例變深、變寬;如果希望小一點,就把這個數(shù)字改小一點,網(wǎng)絡就會按比例變淺、變窄。

anchors 解讀

yolov5 初始化了 9 個 anchors,分別在三個特征圖 (feature map)中使用,每個 feature map 的每個 grid cell 都有三個 anchor 進行預測。 分配規(guī)則:

  • 尺度越大的 feature map 越靠前,相對原圖的下采樣率越小,感受野越小, 所以相對可以預測一些尺度比較小的物體(小目標),分配到的 anchors 越小。
  • 尺度越小的 feature map 越靠后,相對原圖的下采樣率越大,感受野越大, 所以可以預測一些尺度比較大的物體(大目標),所以分配到的 anchors 越大。
  • 即在小特征圖(feature map)上檢測大目標,中等大小的特征圖上檢測中等目標, 在大特征圖上檢測小目標。

backbone & head解讀

[from, number, module, args] 參數(shù)
四個參數(shù)的意義分別是:

  • 第一個參數(shù) from :從哪一層獲得輸入,-1表示從上一層獲得,[-1, 6]表示從上層和第6層兩層獲得。
  • 第二個參數(shù) number:表示有幾個相同的模塊,如果為9則表示有9個相同的模塊。
  • 第三個參數(shù) module:模塊的名稱,這些模塊寫在common.py中。
  • 第四個參數(shù) args:類的初始化參數(shù),用于解析作為 moudle 的傳入?yún)?shù),即[ch_out, kernel, stride, padding, groups][輸出通道數(shù)量,卷積核尺寸,步長,padding],這里連ch_in都省去了,因為輸入都是上層的輸出(初始ch_in為3)

Backbone骨干網(wǎng)絡

骨干網(wǎng)絡是指用來提取圖像特征的網(wǎng)絡,它的主要作用是將原始的輸入圖像轉化為多層特征圖,以便后續(xù)的目標檢測任務使用。在Yolov5中,使用的是CSPDarknet53或ResNet骨干網(wǎng)絡。Backbone中的主要結構有Conv模塊、C3模塊、SPPF模塊。

Conv

Conv模塊是卷積神經(jīng)網(wǎng)絡中常用的一種基礎模塊,它主要由卷積層、BN層和激活函數(shù)組成。下面對這些組成部分進行詳細解析。

  • 卷積層是卷積神經(jīng)網(wǎng)絡中最基礎的層之一,用于提取輸入特征中的局部空間信息。
  • BN層是在卷積層之后加入的一種歸一化層,用于規(guī)范化神經(jīng)網(wǎng)絡中的特征值分布。
  • 激活函數(shù)是一種非線性函數(shù),用于給神經(jīng)網(wǎng)絡引入非線性變換能力。常用的激活函數(shù)包括sigmoid、ReLU、LeakyReLU、ELU等。

C3模塊

C3模塊是YOLOv5網(wǎng)絡中的一個重要組成部分,其主要作用是增加網(wǎng)絡的深度和感受野,提高特征提取的能力。

C3模塊是由三個Conv塊構成的,其中第一個Conv塊的步幅為2,可以將特征圖的尺寸減半,第二個Conv塊和第三個Conv塊的步幅為1。C3模塊中的Conv塊采用的都是3x3的卷積核。在每個Conv塊之間,還加入了BN層和LeakyReLU激活函數(shù),以提高模型的穩(wěn)定性和泛化性能。

Neck特征金字塔

在Neck部分的變化還是相對較大的,首先是將SPP換成成了SPPF,其次是New CSP-PAN了,在YOLOv4中,Neck的PAN結構是沒有引入CSP結構的,但在YOLOv5中作者在PAN結構中加入了CSP。

SPPF模塊

SPP

SPP模塊是何凱明大神在2015年的論文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》中被提出。

SPP全程為空間金字塔池化結構,主要是為了解決兩個問題:

  • 有效避免了對圖像區(qū)域裁剪、縮放操作導致的圖像失真等問題;
  • 解決了卷積神經(jīng)網(wǎng)絡對圖相關重復特征提取的問題,大大提高了產(chǎn)生候選框的速度,且節(jié)省了計算成本。
    YOLOv5網(wǎng)絡結構,訓練策略詳解
class SPP(nn.Module):
    # Spatial Pyramid Pooling (SPP) layer https://arxiv.org/abs/1406.4729
    def __init__(self, c1, c2, k=(5, 9, 13)):
        super().__init__()
        c_ = c1 // 2  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
        self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])

    def forward(self, x):
        x = self.cv1(x)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning
            return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
SPPF

這個是YOLOv5作者Glenn Jocher基于SPP提出的,速度較SPP快很多,所以叫SPP-Fast.
YOLOv5網(wǎng)絡結構,訓練策略詳解

class SPPF(nn.Module):
    # Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher
    def __init__(self, c1, c2, k=5):  # equivalent to SPP(k=(5, 9, 13))
        super().__init__()
        c_ = c1 // 2  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_ * 4, c2, 1, 1)
        self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)

    def forward(self, x):
        x = self.cv1(x)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')  # suppress torch 1.9.0 max_pool2d() warning
            y1 = self.m(x)
            y2 = self.m(y1)
            return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))

CSP-PAN

在Neck部分另外一個不同點就是New CSP-PAN了,在YOLOv4中,Neck的PAN結構是沒有引入CSP結構的,但在YOLOv5中作者在PAN結構中加入了CSP。

CSP

YOLOv5s的CSP結構是將原輸入分成兩個分支,分別進行卷積操作使得通道數(shù)減半,然后一個分支進行Bottleneck * N操作,然后concat兩個分支,使得BottlenneckCSP的輸入與輸出是一樣的大小,這樣是為了讓模型學習到更多的特征。

YOLOv5中的CSP有兩種設計,分別為CSP1_X結構和CSP2_X結構。

PAN

Yolov5 的 Neck 部分采用了 PANet 結構,Neck 主要用于生成特征金字塔。特征金字塔會增強模型對于不同縮放尺度對象的檢測,從而能夠識別不同大小和尺度的同一個物體。

PANet 結構是在FPN的基礎上引入了 Bottom-up path augmentation 結構。

PANet[1]最大的貢獻是提出了一個自頂向下和自底向上的雙向融合骨干網(wǎng)絡,同時在最底層和最高層之間添加了一條“short-cut”,用于縮短層之間的路徑。PANet還提出了自適應特征池化(Adaptive Features Pooling)和全連接融合(Fully-connected Fusion)兩個模塊。其中自適應特征池化可以用于聚合不同層之間的特征,保證特征的完整性和多樣性,而通過全連接融合可以得到更加準確的預測mask。
YOLOv5網(wǎng)絡結構,訓練策略詳解

Head目標檢測頭

目標檢測頭是用來對特征金字塔進行目標檢測的部分,它包括了一些卷積層、池化層和全連接層等。
head中的主體部分就是三個Detect檢測器,即利用基于網(wǎng)格的anchor在不同尺度的特征圖上進行目標檢測的過程。

head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13
?
   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
?
   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
?
   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
?
   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

數(shù)據(jù)增強

1.Mosaic數(shù)據(jù)增強

將四張圖片拼成一張圖片,采用隨機縮放、隨機裁剪、隨機排布的方式進行拼接。
YOLOv5網(wǎng)絡結構,訓練策略詳解

優(yōu)點:

  1. 豐富數(shù)據(jù)集
  2. 減少GPU

2.Copy paste數(shù)據(jù)增強

將部分目標隨機的粘貼到圖片中,前提是數(shù)據(jù)要有segments數(shù)據(jù)才行,即每個目標的實例分割信息。
YOLOv5網(wǎng)絡結構,訓練策略詳解

3. Random affine仿射變換

yolov5的仿射變換包含隨機旋轉、平移、縮放、錯切操作,和yolov3-spp一樣,代碼都沒有改變。據(jù)配置文件里的超參數(shù)發(fā)現(xiàn)只使用了Scale和Translation即縮放和平移。
YOLOv5網(wǎng)絡結構,訓練策略詳解

4. MixUp數(shù)據(jù)增強

就是將兩張圖片按照一定的透明度融合在一起。
YOLOv5網(wǎng)絡結構,訓練策略詳解

5. HSV(Augment HSV(Hue, Saturation, Value))隨機增強圖像

隨機調整色度,飽和度以及明度。
YOLOv5網(wǎng)絡結構,訓練策略詳解

6.Random horizontal flip隨機水平翻轉

隨機上下左右的水平翻轉
YOLOv5網(wǎng)絡結構,訓練策略詳解

7. Cutout數(shù)據(jù)增強

Cutout是一種新的正則化方法。訓練時隨機把圖片的一部分減掉,這樣能提高模型的魯棒性。它的來源是計算機視覺任務中經(jīng)常遇到的物體遮擋問題。通過cutout生成一些類似被遮擋的物體,不僅可以讓模型在遇到遮擋問題時表現(xiàn)更好,還能讓模型在做決定時更多地考慮環(huán)境。

Cutout數(shù)據(jù)增強在之前也見過很多次了。在yolov5的代碼中默認也是不啟用的。
YOLOv5網(wǎng)絡結構,訓練策略詳解

8. Albumentations數(shù)據(jù)增強工具包

該工具最大的好處是會根據(jù)你使用的數(shù)據(jù)增強方法自動修改標注框信息!

albumentations 是一個給予 OpenCV的快速訓練數(shù)據(jù)增強庫,擁有非常簡單且強大的可以用于多種任務(分割、檢測)的接口,易于定制且添加其他框架非常方便。

它可以對數(shù)據(jù)集進行逐像素的轉換,如模糊、下采樣、高斯造點、高斯模糊、動態(tài)模糊、RGB轉換、隨機霧化等;也可以進行空間轉換(同時也會對目標進行轉換),如裁剪、翻轉、隨機裁剪等。

github地址:https://github.com/albumentations-team/albumentations
docs使用文檔:https://albumentations.ai/docs
YOLOv5網(wǎng)絡結構,訓練策略詳解
YOLOv5網(wǎng)絡結構,訓練策略詳解

YOLOV5的訓練技巧

1.訓練預熱 Warmup

剛開始訓練時,模型的權重是隨機初始化的,此時若選擇一個較大的學習率,可能帶來模型的不穩(wěn)定(振蕩)。選擇Warmup預熱學習率的方式可以使得開始訓練的幾個epoches或者一些steps內(nèi)學習率較小,在預熱的小學習率下,模型可以慢慢趨于穩(wěn)定,等模型相對穩(wěn)定后再選擇預先設置的學習率進行訓練,使得模型收斂速度變得更快,模型效果更佳。

常見Warmup類型
  1. Constant Warmup
    在前面100epoch里,學習率線性增加,大于100epoch以后保持不變
  2. Constant Warmup
    在前面100epoch里,學習率線性增加,大于100epoch以后保持不變
  3. Constant Warmup
    在前面100epoch里,學習率線性增加,大于100epoch以后保持不變

超參數(shù)設置
在yolov5中data/hyps/hyp.scratch-*.yaml三個文件中,都存在著warmup_epoch代表訓練預熱輪次

2. 自動調整錨定框——Autoanchor

預定義邊框就是一組預設的邊框,在訓練時,以真實的邊框位置相對于預設邊框的偏移來構建(也就是我們打下的標簽)

訓練樣本。 這就相當于,預設邊框先大致在可能的位置“框“出來目標,然后再在這些預設邊框的基礎上進行調整。

一個Anchor Box可以由:邊框的縱橫比和邊框的面積(尺度)來定義,相當于一系列預設邊框的生成規(guī)則,根據(jù)Anchor Box,可以在圖像的任意位置,生成一系列的邊框

3.超參數(shù)進化

yolov5提供了一種超參數(shù)優(yōu)化的方法–Hyperparameter Evolution,即超參數(shù)進化。超參數(shù)進化是一種利用 遺傳算法(GA) 進行超參數(shù)優(yōu)化的方法,我們可以通過該方法選擇更加合適自己的超參數(shù)。

提供的默認參數(shù)也是通過在COCO數(shù)據(jù)集上使用超參數(shù)進化得來的。由于超參數(shù)進化會耗費大量的資源和時間,如果默認參數(shù)訓練出來的結果能滿足你的使用,使用默認參數(shù)也是不錯的選擇。

4.凍結訓練——Freeze training

凍結訓練的作用:當我們已有部分預訓練權重,這部分預訓練權重所應用的那部分網(wǎng)絡是通用的,如骨干網(wǎng)絡,那么我們可以先凍結這部分權重的訓練,將更多的資源放在訓練后面部分的網(wǎng)絡參數(shù),這樣使得時間和資源利用都能得到很大改善。然后后面的網(wǎng)絡參數(shù)訓練一段時間之后再解凍這些被凍結的部分,這時再全部一起訓練。

5.多尺度訓練——multi-scale training

當前的多尺度訓練(Multi Scale Training,MST)通常是指設置幾種不同的圖片輸入尺度,訓練時從多個尺度中隨機選取一種尺度,將輸入圖片縮放到該尺度并送入網(wǎng)絡中,是一種簡單又有效的提升多尺度物體檢測的方法。雖然一次迭代時都是單一尺度的,但每次都各不相同,增加了網(wǎng)絡的魯棒性,又不至于增加過多的計算量。而在測試時,為了得到更為精準的檢測結果,也可以將測試圖片的尺度放大,例如放大4倍,這樣可以避免過多的小物體。

6. 加權圖像策略

圖像加權策略可以解決樣本不平衡的,具體操作步驟圖下:
根據(jù)樣本種類分布使用圖像調用頻率不同的方法解決。
1、讀取訓練樣本中的GT,保存為一個列表;
2、計算訓練樣本列表中不同類別個數(shù),然后給每個類別按相應目標框數(shù)的倒數(shù)賦值,數(shù)目越多的種類權重越小,形成按種類的分布直方圖;
3、對于訓練數(shù)據(jù)列表,訓練時按照類別權重篩選出每類的圖像作為訓練數(shù)據(jù)。使用random.choice(population, weights=None, *, cum_weights=None, k=1)更改訓練圖像索引,可達到樣本均衡的效果。

7.矩形推理——Rectangular Inference

通常YOLO系列網(wǎng)絡的輸入都是預處理后的方形圖像數(shù)據(jù),如416 * 416、608 * 608。當原始圖像為矩形時,會將其填充為方形(如下圖:方形輸入),但是填充的灰色區(qū)域其實就是冗余信息,不論是在訓練還是推理階段,這些冗余信息都會增加耗時。

為了減少圖像的冗余數(shù)據(jù),輸入圖像由方形改為矩形(如下圖:矩形輸入):將長邊resize為固定尺寸(如416),短邊按同樣比例resize,然后把短邊的尺寸盡量少地填充為32的倍數(shù)。

這種方法在推理階段稱為矩形推理(Rectangular Inference),在訓練階段則稱為矩形訓練(Rectangular Training)。推理階段直接對圖像進行resize和pad就行,但是訓練階段輸入的是一個批次的圖像集合,需要保持批次內(nèi)的圖像尺寸一致,因此處理邏輯相對復雜一些。

8.非極大值抑制——NMS

在目標檢測的預測階段時,會輸出許多候選的anchor box,其中有很多是明顯重疊的預測邊界框都圍繞著同一個目標,這時候我就可以使用NMS來合并同一目標的類似邊界框,或者說是保留這些邊界框中最好的一個。

9. 斷點訓練

在用yolov5訓練數(shù)據(jù)的過程中由于突發(fā)情況訓練過程突然中斷,從頭訓練耗時,想接著上次訓練繼續(xù)訓練怎么辦。放心,在yolov5中給我們提供現(xiàn)成的參數(shù)–resume

10.早停機制(Early Stopping)

patience:訓練了多少個epoch,如果模型效果未提升,就讓模型提前停止訓練。
fitness監(jiān)控的是增大的數(shù)值,例如mAP,如果mAP在連續(xù)訓練patience次內(nèi)沒有增加就停止訓練。文章來源地址http://www.zghlxwxcb.cn/news/detail-417109.html

11.多GPU訓練

到了這里,關于YOLOv5網(wǎng)絡結構,訓練策略詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包