精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美第十八页| 超碰国产精品一区二页| 2020日本不卡一区二区视频| 国产69精品久久久久久| 日本人亚洲人jjzzjjz| 91精品国产66| 亚洲黄色录像片| 91视频婷婷| aaa人片在线| 欧美电影《睫毛膏》| 亚洲国产精品va在看黑人| 亚洲人成无码www久久久| 老司机午夜在线| 成人精品视频一区| 国产精品美女网站| 久久久久无码国产精品| 欧美系列电影免费观看 | 天天夜碰日日摸日日澡性色av| 免费一级在线观看| 国产成人综合亚洲网站| 国产成人在线亚洲欧美| 欧美成人精品欧美一| 亚洲小说图片| 精品国精品自拍自在线| 91制片厂毛片| 蜜桃av.网站在线观看| 亚洲图片欧美激情| 日本午夜精品一区二区三区| www.天堂在线| 精品制服美女丁香| 欧美最猛性xxxxx(亚洲精品)| 日本青青草视频| 日韩aaaa| 国产亚洲精品久久久久久牛牛| 国产精品熟妇一区二区三区四区 | 福利精品视频| 91女人18毛片水多国产| 日韩二区三区四区| 欧洲s码亚洲m码精品一区| 九九视频免费看| 亚洲精品成人| 正在播放国产一区| 中文字幕av观看| 国产成人精品亚洲线观看| 欧美一区二区三区的| 91日韩视频在线观看| 久九九久频精品短视频| 色综合久久66| 国产亚洲天堂网| 超黄网站在线观看| 亚洲一区二区不卡免费| 特级西西人体www高清大胆| 嫩草香蕉在线91一二三区| 国产三级精品视频| 日韩中文字幕一区| 国产高清视频免费最新在线| 久久婷婷色综合| 免费观看国产成人| 蜜桃免费在线| 欧美激情一区不卡| 一区二区视频在线播放| 瑟瑟视频在线| 亚洲欧美色综合| 91看片淫黄大片91| 日本h片在线| 亚洲第一在线综合网站| 秋霞无码一区二区| 亚洲优女在线| 在线亚洲免费视频| 亚洲成人福利在线| 亚洲精品自拍| 日韩欧美中文字幕制服| 中文字幕制服丝袜| 久久精品色播| 亚洲天堂开心观看| 亚洲精品午夜视频| 欧美残忍xxxx极端| 欧美丰满少妇xxxxx做受| 国产精品2020| 久久久久久久高潮| 国产日韩欧美电影在线观看| 国产chinasex对白videos麻豆| 国产成人精品亚洲日本在线桃色| 国产综合色一区二区三区| 欧美日韩在线中文字幕| 国产精品久久久久aaaa| 久久www视频| 中文字幕在线高清| 欧美剧在线免费观看网站 | 日韩中文字幕视频| 波多野结衣亚洲色图| 99视频在线精品国自产拍免费观看| 91精品国产91| 中文字幕码精品视频网站| 国产精品影视网| 久久综合久久久| 黄色成人在线观看| 午夜国产精品影院在线观看| 黄色av免费在线播放| 精品一区视频| 亚洲精品中文字幕有码专区| 久久福利免费视频| 翔田千里一区二区| 91综合免费在线| 飘雪影视在线观看免费观看| 1024成人网色www| 欧美 日韩精品| 日韩精品一区二区三区中文在线 | 欧美三级黄网| 亚洲va欧美va天堂v国产综合| 日韩中文字幕组| jizz久久精品永久免费| 在线观看国产欧美| 精品91久久久| 国产精品白丝jk黑袜喷水| 欧美男人的天堂| 手机电影在线观看| 欧美曰成人黄网| 中文字幕一区二区久久人妻网站| 亚洲一区二区三区| 国产大片精品免费永久看nba| www.色视频| 亚洲婷婷在线视频| 国产wwwxx| 亚洲女娇小黑人粗硬| 欧美激情小视频| 国产精品美女一区| 国产亚洲精品bt天堂精选| av无码久久久久久不卡网站| 91麻豆精品一二三区在线| 国产香蕉一区二区三区在线视频| 久久丫精品久久丫| 国产精品一区二区久久不卡| 亚洲一区美女| www.国产精品| 亚洲欧美制服另类日韩| 天天操天天干视频| 国产又粗又大又爽| 国产成人精品免费网站| 人人妻人人澡人人爽精品欧美一区| 玛雅亚洲电影| 亚洲美女在线观看| av大片免费观看| 99精品欧美一区| 黄色成人在线看| 国产精品videossex| 九九热精品视频国产| 国产女人18毛片水真多| 亚洲欧洲精品成人久久奇米网| 欧美性猛交xxx乱久交| 在线观看欧美理论a影院| 91高清在线免费观看| 污视频在线免费观看| 亚洲成a人片在线不卡一二三区 | 波多野结衣黄色网址| 久久在线观看免费| 日本黄网站免费| 精品成人影院| 国产欧美日韩中文字幕在线| 永久av在线| 91精品国产麻豆| 欧美成人免费看| 国产成人av电影| 日韩日韩日韩日韩日韩| 欧美福利在线播放网址导航| 91sa在线看| 国产在线高清| 欧美日韩高清影院| 亚洲最大的黄色网址| 国内一区二区视频| 日韩精品一区二区在线视频| 国产精品网在线观看| 欧美有码在线视频| 成人精品一区二区三区免费| 欧美精品久久天天躁| 欧美黑吊大战白妞| 99r国产精品| 爱情岛论坛vip永久入口| 999国产精品永久免费视频app| 97超级碰碰| 日韩电影毛片| 中文字幕亚洲情99在线| www男人的天堂| 日韩欧美精品中文字幕| 亚洲天堂精品一区| 丁香一区二区三区| 最近免费中文字幕中文高清百度| 亚洲情侣在线| 好看的日韩精品视频在线| 电影一区电影二区| 精品自在线视频| 日本私人网站在线观看| 欧美日韩激情一区| 国产亚洲精品女人久久久久久| 97久久精品人人爽人人爽蜜臀| 免费涩涩18网站入口| 欧美高清一区| 欧美精品一区三区在线观看| 国产精品一区二区三区www| 性欧美xxxx| 在线观看黄av| 日韩av在线网| av网站免费大全| 色网站国产精品| 欧美激情国产精品免费| 国产三级精品视频| 国产精品伦子伦| 韩国成人福利片在线播放| 日韩精品 欧美| 亚洲电影在线一区二区三区| 开心色怡人综合网站| 欧美激情精品| 国产精品久久在线观看| 免费成人在线电影| 麻豆乱码国产一区二区三区| 你懂的在线看| 亚洲成av人乱码色午夜| 亚洲天堂999| 日韩欧美中文免费| 一级aaa毛片| 综合欧美一区二区三区| 精品无人区无码乱码毛片国产 | 欧美精品xxxxbbbb| 日本中文字幕第一页| 亚洲一区视频在线观看视频| 国产精品久久国产精麻豆96堂| 91一区二区在线观看| 国产成人av免费观看| 狠狠色狠狠色综合| 欧美特级aaa| 久久先锋影音| 中国丰满人妻videoshd| 亚洲激情午夜| avav在线播放| 中文在线日韩| 成人在线观看毛片| 亚洲九九视频| 一区二区免费在线观看| 奇米影视亚洲| 婷婷四房综合激情五月| 精品国产午夜| 日韩高清国产一区在线观看| 亚洲精品合集| 欧美大陆一区二区| 欧美美女在线直播| 久久资源av| 亚洲动漫精品| 欧美二区在线看| 久久av资源| 日韩免费av一区二区三区| 蜜桃一区二区三区| 久久久久资源| 国产一区二区三区四区| 日韩一区国产在线观看| 日韩欧美国产精品综合嫩v| 色噜噜狠狠一区二区三区| 凹凸成人精品亚洲精品密奴| 亚洲综合网中心| 亚州av乱码久久精品蜜桃| 国产欧美自拍视频| 欧美三区视频| 欧美a在线视频| 天堂蜜桃91精品| 在线免费观看视频黄| 精品一区二区三区在线观看国产 | 欧美区在线播放| 国产黄色大片在线观看| 91精品国产九九九久久久亚洲| 成人短视频app| 国产精品女人网站| 99久久99九九99九九九| 96久久精品| 亚洲人亚洲人色久| 午夜精品一区二区在线观看 | 国外成人在线播放| 成人性生活av| 国产原创欧美精品| 永久免费精品视频| 蜜桃视频成人| 国产精品久久久久一区二区三区厕所 | 亚洲精品你懂的| 色在线观看视频| 黑人狂躁日本妞一区二区三区| 中文在线免费观看| 日韩你懂的在线观看| 天堂av电影在线观看| 深夜福利国产精品| 欧美大片黄色| 欧洲成人性视频| aa亚洲一区一区三区| 精品国产免费人成电影在线观...| 精品国产午夜| 丁香婷婷综合激情| 日本中文一区二区三区| 国产a级片视频| 久久精品在线观看| 激情四射综合网| 在线观看日韩电影| 亚洲av综合色区无码一二三区| 亚洲欧美一区二区三区四区| 成人国产免费电影| 欧美专区国产专区| 亚洲一二av| 亚洲一区二区三区免费看| 99精品视频免费观看视频| 91女神在线观看| 91老师片黄在线观看| 日韩视频中文字幕在线观看| 色视频成人在线观看免| 内射后入在线观看一区| 少妇激情综合网| 桃子视频成人app| 国产69精品久久久久9999apgf | 久久久国产精品入口麻豆| 欧美亚洲丝袜| 亚洲国产二区| 天堂网成人在线| 日本一二三不卡| 综合激情网五月| 精品国产免费一区二区三区香蕉| 日韩毛片久久久| 国产成人免费av电影| heyzo欧美激情| 路边理发店露脸熟妇泻火| 麻豆一区二区三区| 国产手机在线观看| 精品欧美国产一区二区三区| 亚洲成人777777| 美女久久久久久久久久久| 玖玖精品在线| 午夜精品一区二区三区四区 | 一区二区三区不卡视频在线观看 | 影视一区二区三区| 久久96国产精品久久99软件| 欧美日韩国产一区精品一区| 午夜免费福利网站| 亚洲欧洲av在线| 一区二区不卡视频在线观看| 色av吧综合网| 天天综合在线观看| 伊人久久大香线蕉精品| 天堂精品中文字幕在线| 精品无码一区二区三区| 欧美日韩综合视频| 日韩精品123| 日韩av大片免费看| 亚洲福利天堂| 乱子伦视频在线看| 久久久精品人体av艺术| 中文字幕第四页| 亚洲人成在线免费观看| 天堂av在线网| 日本一区二区在线视频观看| 日韩精品1区2区3区| 精品人妻无码一区| 欧美午夜电影在线播放| 三级外国片在线观看视频| 成人网欧美在线视频| 欧美精品麻豆| 亚洲中文字幕无码一区| 欧美视频第一页| 国产视频网址在线| 国产欧美日韩中文字幕| 午夜天堂精品久久久久| 五月天丁香社区| 欧美日韩一区二区三区在线免费观看 | 羞羞视频在线观看一区二区| 黄色a级在线观看| 丁香婷婷综合激情五月色| 久久高清免费视频| 国产亚洲精品久久久久动| 91成人短视频在线观看| 超碰人人爱人人| 91香蕉视频黄| 亚洲天堂视频在线| 久久成人18免费网站| 精品伊人久久久| 国产一二三四在线视频| 玉米视频成人免费看| 天天av综合网| 国产欧美最新羞羞视频在线观看| 亚洲天天综合| 亚洲精品乱码久久| 欧美性生交片4| 国产精品蜜臀| 亚洲欧美丝袜| 成人久久久精品乱码一区二区三区 | 无码成人精品区在线观看| 色av一区二区| 国产无遮挡又黄又爽| www国产精品av| 在线永久看片免费的视频| 北条麻妃久久精品| 久久国产精品色av免费看| 黄大色黄女片18第一次| 亚洲第一久久影院| 免费高清完整在线观看| 久久久国产精品一区二区三区| 美女高潮久久久| 日韩成人高清视频|