精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Grad-CAM的詳細介紹和Pytorch代碼實現

開發 前端
Grad-CAM (Gradient-weighted Class Activation Mapping) 是一種可視化深度神經網絡中哪些部分對于預測結果貢獻最大的技術。它能夠定位到特定的圖像區域,從而使得神經網絡的決策過程更加可解釋和可視化。

Grad-CAM (Gradient-weighted Class Activation Mapping) 是一種可視化深度神經網絡中哪些部分對于預測結果貢獻最大的技術。它能夠定位到特定的圖像區域,從而使得神經網絡的決策過程更加可解釋和可視化。

Grad-CAM 的基本思想是,在神經網絡中,最后一個卷積層的輸出特征圖對于分類結果的影響最大,因此我們可以通過對最后一個卷積層的梯度進行全局平均池化來計算每個通道的權重。這些權重可以用來加權特征圖,生成一個 Class Activation Map (CAM),其中每個像素都代表了該像素區域對于分類結果的重要性。

相比于傳統的 CAM 方法,Grad-CAM 能夠處理任意種類的神經網絡,因為它不需要修改網絡結構或使用特定的層結構。此外,Grad-CAM 還可以用于對特征的可視化,以及對網絡中的一些特定層或單元進行分析。

在Pytorch中,我們可以使用鉤子 (hook) 技術,在網絡中注冊前向鉤子和反向鉤子。前向鉤子用于記錄目標層的輸出特征圖,反向鉤子用于記錄目標層的梯度。在本篇文章中,我們將詳細介紹如何在Pytorch中實現Grad-CAM。

圖片

加載并查看預訓練的模型

為了演示Grad-CAM的實現,我將使用來自Kaggle的胸部x射線數據集和我制作的一個預訓練分類器,該分類器能夠將x射線分類為是否患有肺炎。

model_path = "your/model/path/"

# instantiate your model
model = XRayClassifier()

# load your model. Here we're loading on CPU since we're not going to do
# large amounts of inference
model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu')))

# put it in evaluation mode for inference
model.eval()

首先我們看看這個模型的架構。就像前面提到的,我們需要識別最后一個卷積層,特別是它的激活函數。這一層表示模型學習到的最復雜的特征,它最有能力幫助我們理解模型的行為,下面是我們這個演示模型的代碼:

import torch
import torch.nn as nn
import torch.nn.functional as F

# hyperparameters
nc = 3 # number of channels
nf = 64 # number of features to begin with
dropout = 0.2
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# setup a resnet block and its forward function
class ResNetBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super(ResNetBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)

self.shortcut = nn.Sequential()
if stride != 1 or in_channels != out_channels:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_channels)
)

def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out

# setup the final model structure
class XRayClassifier(nn.Module):
def __init__(self, nc=nc, nf=nf, dropout=dropout):
super(XRayClassifier, self).__init__()

self.resnet_blocks = nn.Sequential(
ResNetBlock(nc, nf, stride=2), # (B, C, H, W) -> (B, NF, H/2, W/2), i.e., (64,64,128,128)
ResNetBlock(nf, nf*2, stride=2), # (64,128,64,64)
ResNetBlock(nf*2, nf*4, stride=2), # (64,256,32,32)
ResNetBlock(nf*4, nf*8, stride=2), # (64,512,16,16)
ResNetBlock(nf*8, nf*16, stride=2), # (64,1024,8,8)
)

self.classifier = nn.Sequential(
nn.Conv2d(nf*16, 1, 8, 1, 0, bias=False),
nn.Dropout(p=dropout),
nn.Sigmoid(),
)

def forward(self, input):
output = self.resnet_blocks(input.to(device))
output = self.classifier(output)
return output

模型3通道接收256x256的圖片。它期望輸入為[batch size, 3,256,256]。每個ResNet塊以一個ReLU激活函數結束。對于我們的目標,我們需要選擇最后一個ResNet塊。

XRayClassifier(
(resnet_blocks): Sequential(
(0): ResNetBlock(
(conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(3, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(1): ResNetBlock(
(conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(2): ResNetBlock(
(conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(3): ResNetBlock(
(conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(4): ResNetBlock(
(conv1): Conv2d(512, 1024, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(shortcut): Sequential(
(0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
)
(classifier): Sequential(
(0): Conv2d(1024, 1, kernel_size=(8, 8), stride=(1, 1), bias=False)
(1): Dropout(p=0.2, inplace=False)
(2): Sigmoid()
)
)

在Pytorch中,我們可以很容易地使用模型的屬性進行選擇。

model.resnet_blocks[-1]
#ResNetBlock(
# (conv1): Conv2d(512, 1024, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
# (bn1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
# (conv2): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
# (bn2): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
# (shortcut): Sequential(
# (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
# (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
# )
#)

Pytorch的鉤子函數

Pytorch有許多鉤子函數,這些函數可以處理在向前或后向傳播期間流經模型的信息。我們可以使用它來檢查中間梯度值,更改特定層的輸出。

在這里,我們這里將關注兩個方法:

register_full_backward_hook(hook, prepend=False)

該方法在模塊上注冊了一個后向傳播的鉤子,當調用backward()方法時,鉤子函數將會運行。后向鉤子函數接收模塊本身的輸入、相對于層的輸入的梯度和相對于層的輸出的梯度

hook(module, grad_input, grad_output) -> tuple(Tensor) or None

它返回一個torch.utils.hooks.RemovableHandle,可以使用這個返回值來刪除鉤子。我們在后面會討論這個問題。

register_forward_hook(hook, *, prepend=False, with_kwargs=False)

這與前一個非常相似,它在前向傳播中后運行,這個函數的參數略有不同。它可以讓你訪問層的輸出:

hook(module, args, output) -> None or modified output

它的返回也是torch.utils.hooks.RemovableHandle

向模型添加鉤子函數

為了計算Grad-CAM,我們需要定義后向和前向鉤子函數。這里的目標是關于最后一個卷積層的輸出的梯度,需要它的激活,即層的激活函數的輸出。鉤子函數會在推理和向后傳播期間為我們提取這些值。

# defines two global scope variables to store our gradients and activations
gradients = None
activations = None

def backward_hook(module, grad_input, grad_output):
global gradients # refers to the variable in the global scope
print('Backward hook running...')
gradients = grad_output
# In this case, we expect it to be torch.Size([batch size, 1024, 8, 8])
print(f'Gradients size: {gradients[0].size()}')
# We need the 0 index because the tensor containing the gradients comes
# inside a one element tuple.

def forward_hook(module, args, output):
global activations # refers to the variable in the global scope
print('Forward hook running...')
activations = output
# In this case, we expect it to be torch.Size([batch size, 1024, 8, 8])
print(f'Activations size: {activations.size()}')

在定義了鉤子函數和存儲激活和梯度的變量之后,就可以在感興趣的層中注冊鉤子,注冊的代碼如下:

backward_hook = model.resnet_blocks[-1].register_full_backward_hook(backward_hook, prepend=False)
forward_hook = model.resnet_blocks[-1].register_forward_hook(forward_hook, prepend=False)

檢索需要的梯度和激活

現在已經為模型設置了鉤子函數,讓我們加載一個圖像,計算gradcam。

from PIL import Image

img_path = "/your/image/path/"
image = Image.open(img_path).convert('RGB')

為了進行推理,我們還需要對其進行預處理:

from torchvision import transforms
from torchvision.transforms import ToTensor

image_size = 256
transform = transforms.Compose([
transforms.Resize(image_size, antialias=True),
transforms.CenterCrop(image_size),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
])

img_tensor = transform(image) # stores the tensor that represents the image

現在就可以進行前向傳播了:

model(img_tensor.unsqueeze(0)).backward()

鉤子函數的返回如下:

Forward hook running...
Activations size: torch.Size([1, 1024, 8, 8])
Backward hook running...
Gradients size: torch.Size([1, 1024, 8, 8])

得到了梯度和激活變量后就可以生成熱圖:

計算Grad-CAM

為了計算Grad-CAM,我們將原始論文公式進行一些簡單的修改:

pooled_gradients = torch.mean(gradients[0], dim=[0, 2, 3])

import torch.nn.functional as F
import matplotlib.pyplot as plt

# weight the channels by corresponding gradients
for i in range(activations.size()[1]):
activations[:, i, :, :] *= pooled_gradients[i]

# average the channels of the activations
heatmap = torch.mean(activations, dim=1).squeeze()

# relu on top of the heatmap
heatmap = F.relu(heatmap)

# normalize the heatmap
heatmap /= torch.max(heatmap)

# draw the heatmap
plt.matshow(heatmap.detach())

結果如下:

圖片

得到的激活包含1024個特征映射,這些特征映射捕獲輸入圖像的不同方面,每個方面的空間分辨率為8x8。通過鉤子獲得的梯度表示每個特征映射對最終預測的重要性。通過計算梯度和激活的元素積可以獲得突出顯示圖像最相關部分的特征映射的加權和。通過計算加權特征圖的全局平均值,可以得到一個單一的熱圖,該熱圖表明圖像中對模型預測最重要的區域。這就是Grad-CAM,它提供了模型決策過程的可視化解釋,可以幫助我們解釋和調試模型的行為。

但是這個圖能代表什么呢?我們將他與圖片進行整合就能更加清晰的可視化了。

結合原始圖像和熱圖

下面的代碼將原始圖像和我們生成的熱圖進行整合顯示:

from torchvision.transforms.functional import to_pil_image
from matplotlib import colormaps
import numpy as np
import PIL

# Create a figure and plot the first image
fig, ax = plt.subplots()
ax.axis('off') # removes the axis markers

# First plot the original image
ax.imshow(to_pil_image(img_tensor, mode='RGB'))

# Resize the heatmap to the same size as the input image and defines
# a resample algorithm for increasing image resolution
# we need heatmap.detach() because it can't be converted to numpy array while
# requiring gradients
overlay = to_pil_image(heatmap.detach(), mode='F')
.resize((256,256), resample=PIL.Image.BICUBIC)

# Apply any colormap you want
cmap = colormaps['jet']
overlay = (255 * cmap(np.asarray(overlay) ** 2)[:, :, :3]).astype(np.uint8)

# Plot the heatmap on the same axes,
# but with alpha < 1 (this defines the transparency of the heatmap)
ax.imshow(overlay, alpha=0.4, interpolation='nearest', extent=extent)

# Show the plot
plt.show()

圖片

這樣看是不是就理解多了。由于它是一個正常的x射線結果,所以并沒有什么需要特殊說明的。

圖片

再看這個例子,這個結果中被標注的是肺炎。Grad-CAM能準確顯示出醫生為確定是否患有肺炎而必須檢查的胸部x光片區域。也就是說我們的模型的確學到了一些東西(紅色區域再肺部附近)

刪除鉤子

要從模型中刪除鉤子,只需要在返回句柄中調用remove()方法。

backward_hook.remove()
forward_hook.remove()

總結

這篇文章可以幫助你理清Grad-CAM 是如何工作的,以及如何用Pytorch實現它。因為Pytorch包含了強大的鉤子函數,所以我們可以在任何模型中使用本文的代碼。


責任編輯:華軒 來源: DeepHub IMBA
相關推薦

2009-07-07 17:01:09

MyServlet

2010-03-18 14:27:53

Java Thread

2024-02-19 15:04:38

自然語言Pytorch人工智能

2009-06-24 13:50:29

JSF和MVC

2011-06-30 10:20:38

JSFMVC

2010-03-29 14:09:12

Oracle ID 自

2010-07-12 14:06:12

SQL Server代

2010-03-18 15:47:07

Java創建線程

2011-07-08 16:24:53

VOPO

2010-03-25 13:19:57

Python_ast.

2010-03-19 10:31:06

Java Socket

2011-06-15 16:58:26

PHP

2010-03-18 14:46:18

Java SynDem

2011-07-22 16:50:05

JAVA

2009-09-02 09:44:01

JSP和JavaBea

2009-08-03 18:49:17

C#和Java

2009-07-03 11:21:43

Servlet和JSPJSP路徑

2010-03-15 17:05:39

Java任務隊列

2023-03-23 16:30:53

PyTorchDDPG算法

2025-01-09 15:57:41

點贊
收藏

51CTO技術棧公眾號

avtt综合网| 久久久久资源| 在线一区亚洲| 免费看毛片的网站| 成年人在线看| 福利片一区二区| 久久久国产精品不卡| 久热在线中文字幕色999舞| 人妻少妇精品久久| 亚洲自拍第二页| 国产免费久久| 亚洲高清三级视频| 91精品在线影院| 国产精品成人在线视频| gay欧美网站| a亚洲天堂av| 欧美激情手机在线视频| 超碰91在线播放| 91在线视频| 日韩成人一区二区三区在线观看| 精品亚洲国产成av人片传媒 | 中国女人一级一次看片| 超碰一区二区三区| 欧洲一区二区三区在线| 色综合视频二区偷拍在线| 欧美特黄aaaaaa| 精品资源在线| 舔着乳尖日韩一区| 久久99精品国产一区二区三区| 一区二区三区免费在线| 99久久夜色精品国产亚洲1000部| 欧美日韩国产综合一区二区| 欧美男人的天堂| 中文人妻av久久人妻18| 国产日产精品_国产精品毛片| 日韩欧美在线123| 日韩国产成人无码av毛片| 国产片高清在线观看| 在线成人激情| 欧美精品一区二区三区蜜桃 | 91啦中文在线| 久久久www免费人成精品| 国产精品成人观看视频免费| 精品无码久久久久| 欧美成人午夜77777| 精品日本高清在线播放| 久久精品99久久| 亚洲国产福利视频| 亚洲精品国产日韩| 亚洲欧美一区二区三区情侣bbw| 亚洲无吗一区二区三区| 精品美女在线观看视频在线观看| 国产精品888| 欧美亚洲在线播放| 日韩av网站在线播放| 日韩精品一区二区三区中文| 精品欧美国产一区二区三区| 久久手机在线视频| 日本性爱视频在线观看| 91麻豆国产福利在线观看| 国产精品免费久久久久影院| 精品国产视频一区二区三区| 红杏aⅴ成人免费视频| 日韩精品中文字幕一区二区三区| 国产老头和老头xxxx×| 亚洲十八**毛片| 国产精品护士白丝一区av| 91系列在线观看| 99久久免费国产精精品| 国产精品自拍一区| 日韩美女视频免费在线观看| 艳妇荡乳欲伦69影片| 久久精品久久久| 日韩精品中文字幕在线| a级大片在线观看| 亚洲综合网站| 欧美日韩精品久久久| 在线观看亚洲色图| 瑟瑟视频在线看| 18涩涩午夜精品.www| 欧美精品人人做人人爱视频| 国产女主播在线直播| 成人综合婷婷国产精品久久蜜臀 | 欧美色网在线| 亚洲欧美日韩综合aⅴ视频| av成人观看| 亚洲综合五月天婷婷丁香| 精品一区二区国语对白| 国产精品久久久久久超碰| 免费三片在线播放| 手机在线电影一区| 精品视频在线播放| 美国黑人一级大黄| 亚洲精品888| 97视频国产在线| 国产亚洲精品成人| 免费看黄裸体一级大秀欧美| 久久久久久久久久国产精品| 91video| 久久av中文字幕片| 国产精品久久久久久久app| 国产人妻精品一区二区三区| 91美女片黄在线| 一区二区三区欧美在线| 岛国视频免费在线观看| 亚洲欧美区自拍先锋| 亚洲乱码一区二区三区 | 亚洲三级在线| 日本精品视频一区二区| 欧美国产亚洲一区| 在线播放免费av| 亚洲天堂免费在线观看视频| 国产h视频在线播放| 国产va免费精品观看精品| 欧美午夜视频网站| 日本免费观看网站| 亚洲精选av| 日韩中文字幕视频| 91香蕉一区二区三区在线观看| 残酷重口调教一区二区| 国产一区二区三区欧美| 欧美18—19性高清hd4k| 亚洲+变态+欧美+另类+精品| 在线成人av影院| 欧美日韩精品区别| 亚洲综合视频| 亚洲精品小视频| 久久综合色综合| 极品少妇xxxx精品少妇| 欧美一区二区高清在线观看| av在线日韩国产精品| 婷婷六月综合网| 人妻互换一二三区激情视频| 久久99精品国产自在现线| 日韩亚洲国产中文字幕| 黄色av网站免费观看| 不卡一区二区在线| 久久天天狠狠| 1区2区3区在线| 欧美性精品220| 91网址在线播放| 亚洲v天堂v手机在线| 91国产美女视频| 无码人妻丰满熟妇精品区| 成人av午夜影院| 丰满的少妇愉情hd高清果冻传媒| 波多野结衣亚洲一二三| 亚洲第一福利网| 欧美 日韩 成人| 手机精品视频在线观看| 成人看片人aa| 四虎在线视频| 国产精品久久久久一区二区三区| www国产免费| 英国三级经典在线观看| 日韩av影视综合网| 国产成人精品视频免费| 黄色免费成人| 国产精品高潮在线| 国产大学生校花援交在线播放| 色婷婷久久99综合精品jk白丝| 黄色片免费网址| 国产成人调教视频在线观看 | 伊人久久大香线蕉成人综合网| 小说区图片区亚洲| 精品毛片乱码1区2区3区| 无码人妻精品一区二区三应用大全| 成人免费在线播放| 国产精品亚洲аv天堂网| 日韩一级片免费在线观看| 久久精品亚洲乱码伦伦中文| 日韩精品无码一区二区三区免费| 亚洲超碰在线观看| 欧美夫妻性视频| 伊人色综合久久久| 亚洲欧洲无码一区二区三区| 欧美精品色视频| 影音先锋久久| 亚洲精品免费网站| 黄色软件在线观看| 亚洲成va人在线观看| www.日本高清| 欧美日韩一卡| 91精品久久久久久久久不口人| 欧美新色视频| 激情成人中文字幕| 久久久视频6r| 老司机午夜精品视频| 亚洲精品国产精品国自产| 国产欧美视频在线| 66m—66摸成人免费视频| av在线女优影院| 亚洲精品一区二区三区香蕉| 亚洲精品91天天久久人人| 26uuu国产电影一区二区| 天天干天天玩天天操| 亚洲精品国产日韩| 正在播放国产精品| 高清一区二区三区| 国产98色在线| 久草在线视频资源| 日韩一区二区三区av| 中文字幕无码日韩专区免费| 不卡av免费在线观看| 欧美美女一级片| 91久久久精品国产| 国产伦精品一区二区三区四区免费| 婷婷丁香在线| 国产亚洲视频在线| 国产自产一区二区| 亚洲成人免费av| 影音先锋男人看片资源| 99精品黄色片免费大全| 亚洲 欧美 日韩 国产综合 在线| 黑人久久a级毛片免费观看| 国产精品久久久久久久久久| 两个人看的在线视频www| 久久亚洲一区二区三区四区五区高| 九色网友自拍视频手机在线| 亚洲成年人在线| 国产男男gay体育生网站| 欧洲一区在线电影| 日本中文在线播放| 久久免费电影网| 无人在线观看的免费高清视频 | 久久国产精品波多野结衣| 欧美经典三级视频一区二区三区| 日韩av手机版| 亚洲在线电影| 国精产品一区一区三区视频| 欧美精品播放| 妞干网这里只有精品| 1313精品午夜理伦电影| 国产精品小说在线| 成人日韩av| 欧美日本黄视频| 色噜噜一区二区三区| 欧美日韩国产在线| 久久久久成人片免费观看蜜芽| 亚洲日本在线视频观看| 国产男女猛烈无遮挡在线喷水| 亚洲国产精品高清| 久草福利在线观看| 国产尤物一区二区在线 | 午夜在线视频观看日韩17c| 青青草国产免费| 国内揄拍国内精品久久| 亚洲色婷婷久久精品av蜜桃| 日韩欧美ww| 久久久综合亚洲91久久98 | 亚洲欧洲中文| 波多野结衣在线观看一区二区| 日韩欧美一区二区三区四区| 国产成人视屏| 91免费视频网站| 欧美成年网站| 国产成人亚洲综合| 国产三区在线观看| 久久深夜福利免费观看| 性网站在线观看| 国内成人精品一区| a天堂中文在线| 色婷婷综合久久久久| 头脑特工队2在线播放| 日韩精品一区二区视频| 黄色影院在线播放| 久久视频中文字幕| 国产乱码在线| 日韩一区二区在线视频| 激情视频在线观看| 欧美激情免费看| 在线免费av资源| 国产日韩欧美视频| 日韩区欧美区| 欧美日韩电影一区二区三区| 日韩国产一区| 欧美另类一区| 天天揉久久久久亚洲精品| www.国产二区| 久久精品人人| 欧美日韩一道本| 日韩极品在线观看| www.成年人| 99精品欧美一区| 黄色片网站在线播放| 一区二区日韩电影| 国产性生活大片| 婷婷开心久久网| 国产又粗又长视频| 欧美日韩中文字幕一区| 超碰在线观看91| 色综合天天综合给合国产| 97精品人妻一区二区三区香蕉| 亚洲成人在线视频播放| 77777影视视频在线观看| 久久久久久有精品国产| 91成人在线| 九色91国产| 一区二区在线影院| 日韩一级在线免费观看| 国产成人亚洲精品青草天美| 五月天精品视频| 亚洲超丰满肉感bbw| 伊人365影院| 亚洲大片精品永久免费| 最近中文字幕免费观看| 亚洲国产欧美一区二区丝袜黑人 | 在线成人av观看| 7777精品伊久久久大香线蕉语言| 欧美网站免费| 成人www视频在线观看| 亚洲va久久| 日韩黄色片在线| 精品一区二区三区免费播放| 中日韩精品一区二区三区| 夜夜精品浪潮av一区二区三区| 中文字幕+乱码+中文| 亚洲精品视频在线观看视频| 爱情岛亚洲播放路线| 亚洲直播在线一区| 色无极亚洲影院| 免费激情视频在线观看| av电影在线观看一区| 久久精品www人人爽人人| 欧美精品九九99久久| 成年人在线看| 国产精品99导航| 免费视频亚洲| 一本一道久久a久久综合精品| 久久成人免费| v天堂中文在线| 亚洲国产aⅴ天堂久久| 亚洲精品18p| 欧美激情视频播放| 亚洲一区二区免费在线观看| 国产在线观看欧美| 国产成人亚洲综合a∨猫咪| 美女福利视频在线观看| 亚洲18女电影在线观看| 精品久久人妻av中文字幕| 亚洲精品久久久久久久久久久久久| 性国产高清在线观看| 亚洲www在线| 女人香蕉久久**毛片精品| 免费 成 人 黄 色| 岛国一区二区在线观看| 国产乡下妇女做爰视频| 欧美性色黄大片| 99青草视频在线播放视| 国产精品老女人精品视频| 欧美日韩中文一区二区| 欧妇女乱妇女乱视频| 成人精品国产免费网站| 国产精品6666| 日韩精品小视频| se01亚洲视频| 亚洲午夜精品国产| 狠狠久久亚洲欧美| 日韩一级片av| 亚洲高清一二三区| 免费看av不卡| 成人动漫在线视频| 最新亚洲一区| 色一情一交一乱一区二区三区| 欧美日韩中文字幕一区| 亚洲淫性视频| 久久超碰亚洲| 喷水一区二区三区| 日韩精品一区二区三区高清免费| 舔着乳尖日韩一区| 粉嫩av一区| 2022国产精品| 国产亚洲福利| 中文在线字幕观看| 国产精品九色蝌蚪自拍| 国产福利资源在线| 久久精品国产亚洲精品| 美女100%一区| 在线视频精品一区| 成人网男人的天堂| 日本中文字幕久久| 亚洲精品一区二区三区影院| 免费电影日韩网站| 一区视频二区视频| 高清在线观看日韩| 国产老头老太做爰视频| 亚洲国产精品99| 日韩福利影视| av在线播放亚洲| 国产精品美女久久久久高潮| 国产香蕉在线观看| 国产精品久在线观看| 亚洲茄子视频| 亚洲精品自拍视频在线观看| 亚洲第一男人天堂| 国产原创一区| 少妇高潮喷水久久久久久久久久| 不卡的av在线| 一本色道久久综合熟妇| 国产91|九色|