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

初學者指南:使用Numpy、Keras和PyTorch實現簡單的線性回歸

人工智能 機器學習
機器學習是人工智能的一門子科學,其中計算機和機器通常學會在沒有人工干預或顯式編程的情況下自行執行特定任務(當然,首先要對他們進行訓練)。

[[433966]]

不同類型的機器學習技術可以劃分到不同類別,如圖 1 所示。方法的選擇取決于問題的類型(分類、回歸、聚類)、數據的類型(圖像、圖形、時間系列、音頻等等)以及方法本身的配置(調優)。 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

在本文中,我們將使用 Python 中最著名的三個模塊來實現一個簡單的線性回歸模型。 使用 Python 的原因是它易于學習和應用。 我們將使用的三個模塊是:

1- Numpy:可以用于數組、矩陣、多維矩陣以及與它們相關的所有操作。

2- Keras:TensorFlow 的高級接口。 它也用于支持和實現深度學習模型和淺層模型。 它是由谷歌工程師開發的。

3- PyTorch:基于 Torch 的深度學習框架。 它是由 Facebook 開發的。

所有這些模塊都是開源的。 Keras 和 PyTorch 都支持使用 GPU 來加快執行速度。

以下部分介紹線性回歸的理論和概念。 如果您已經熟悉理論并且想要實踐部分,可以跳過到下一部分。

線性回歸

它是一種數學方法,可以將一條線與基礎數據擬合。 它假設輸出和輸入之間存在線性關系。 輸入稱為特征或解釋變量,輸出稱為目標或因變量。 輸出變量必須是連續的。 例如,價格、速度、距離和溫度。 以下等式在數學上表示線性回歸模型:

Y = W*X + B

如果把這個方程寫成矩陣形式。 Y 是輸出矩陣,X 是輸入矩陣,W 是權重矩陣,B 是偏置向量。 權重和偏置是線性回歸參數。 有時權重和偏置分別稱為斜率和截距。

訓練該模型的第一步是隨機初始化這些參數。 然后它使用輸入的數據來計算輸出。 通過測量誤差將計算出的輸出與實際輸出進行比較,并相應地更新參數。并重復上述步驟。該誤差稱為 L2 范數(誤差平方和),由下式給出: 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

計算誤差的函數又被稱作損失函數,它可以有不同的公式。 i 是數據樣本數,y 是預測輸出,t 是真實目標。 根據以下等式中給出的梯度下降規則更新參數: 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸  
初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

在這里,(希臘字母 eta)是學習率,它指定參數的更新步驟(更新速度)。 (希臘字母 delta)只是預測輸出和真實輸出之間的差異。 i 代表迭代(所謂的輪次)。 L(W) 是損失函數相對于權重的梯度(導數)。 關于學習率的價值,有一點值得一提。 較小的值會導致訓練速度變慢,而較大的值會導致圍繞局部最小值或發散(無法達到損失函數的局部最小值)的振蕩。 圖 2 總結了以上所有內容。 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

現在讓我們深入了解每個模塊并將上面的方法實現。

Numpy 實現

我們將使用 Google Colab 作為我們的 IDE(集成開發環境),因為它功能強大,提供了所有必需的模塊,無需安裝(部分模塊除外),并且可以免費使用。

為了簡化實現,我們將考慮具有單個特征和偏置 (y = w1*x1 + b) 的線性關系。

讓我們首先導入 Numpy 模塊來實現線性回歸模型和 Matplotlib 進行可視化。 

  1. # Numpy is needed to build the model 
  2. import numpy as np 
  3. # Import the module matplotlib for visualizing the data 
  4. import matplotlib.pyplot as plt 

我們需要一些數據來處理。 數據由一個特征和一個輸出組成。 對于特征生成,我們將從隨機均勻分布中生成 1000 個樣本。 

  1. # We use this line to make the code reproducible (to get the same results when running) 
  2. np.random.seed(42) 
  3. First, we should declare a variable containing the size of the training set we want to generate 
  4. observations = 1000 
  5. # Let us assume we have the following relationship 
  6. # y = 13x + 2 
  7. # y is the output and x is the input or feature 
  8. # We generate the feature randomly, drawing from an uniform distribution. There are 3 arguments of this method (low, high, size). 
  9. # The size of x is observations by 1. In this case: 1000 x 1. 
  10. x = np.random.uniform(low=-10, high=10, size=(observations,1)) 
  11. # Let us print the shape of the feature vector 
  12. print (x.shape) 

為了生成輸出(目標),我們將使用以下關系: 

  1. Y = 13 * X + 2 + 噪聲 

這就是我們將嘗試使用線性回歸模型來估計的。 權重值為 13,偏置為 2。噪聲變量用于添加一些隨機性。 

  1. np.random.seed(42) 
  2. # We add a small noise to our function for more randomness 
  3. noise = np.random.uniform(-1, 1, (observations,1)) 
  4. # Produce the targets according to the f(x) = 13x + 2 + noise definition. 
  5. # This is a simple linear relationship with one weight and bias. 
  6. In this way, we are basically saying: the weight is 13 and the bias is 2. 
  7. targets = 13*x + 2 + noise 
  8. Check the shape of the targets just in case. It should be n x m, where n is the number of samples 
  9. and m is the number of output variables, so 1000 x 1. 
  10. print (targets.shape) 

讓我們繪制生成的數據。 

  1. # Plot x and targets 
  2. plt.plot(x,targets) 
  3. Add labels to x axis and y axis 
  4. plt.ylabel('Targets'
  5. plt.xlabel('Input'
  6. Add title to the graph 
  7. plt.title('Data'
  8. # Show the plot 
  9. plt.show() 

圖 3 顯示了這種線性關系: 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

對于模型訓練,我們將從參數的一些初始值開始。 它們是從給定范圍內的隨機均勻分布生成的。 您可以看到這些值與真實值相差甚遠。 

  1. np.random.seed(42) 
  2. # We will initialize the weights and biases randomly within a small initial range. 
  3. # init_range is the variable that will measure that. 
  4. init_range = 0.1 
  5. # Weights are of size k x m, where k is the number of input variables and m is the number of output variables 
  6. In our case, the weights matrix is 1 x 1, since there is only one input (x) and one output (y) 
  7. weights = np.random.uniform(low=-init_range, high=init_range, size=(1, 1)) 
  8. # Biases are of size 1 since there is only 1 output. The bias is a scalar. 
  9. biases = np.random.uniform(low=-init_range, high=init_range, size=1) 
  10. # Print the weights to get a sense of how they were initialized. 
  11. # You can see that they are far from the actual values
  12. print (weights) 
  13. print (biases) 
  14. [[-0.02509198]] 
  15. [0.09014286] 

我們還為我們的訓練設置了學習率。 我們選擇了 0.02 的值。 這里可以通過嘗試不同的值來探索性能。 我們有了數據,初始化了參數,并設置了學習率,已準備好開始訓練過程。 我們通過將 epochs 設置為 100 來迭代數據。在每個 epoch 中,我們使用初始參數來計算新輸出并將它們與實際輸出進行比較。 損失函數用于根據前面提到的梯度下降規則更新參數。 新更新的參數用于下一次迭代。 這個過程會不斷重復,直到達到 epoch 數。 可以有其他停止訓練的標準,但我們今天不討論它。 

  1. Set some small learning rate  
  2. # 0.02 is going to work quite well for our example. Once again, you can play around with it. 
  3. # It is HIGHLY recommended that you play around with it. 
  4. learning_rate = 0.02 
  5. # We iterate over our training dataset 100 times. That works well with a learning rate of 0.02. 
  6. # We call these iteration epochs. 
  7. # Let us define a variable to store the loss of each epoch. 
  8. losses = [] 
  9. for i in range (100): 
  10.  
  11. # This is the linear model: y = xw + b equation 
  12. outputs = np.dot(x,weights) + biases 
  13. # The deltas are the differences between the outputs and the targets 
  14. # Note that deltas here is a vector 1000 x 1 
  15. deltas = outputs - targets 
  16.  
  17. # We are considering the L2-norm loss as our loss function (regression problem), but divided by 2. 
  18. # Moreover, we further divide it by the number of observations to take the mean of the L2-norm. 
  19. loss = np.sum(deltas ** 2) / 2 / observations 
  20.  
  21. # We print the loss function value at each step so we can observe whether it is decreasing as desired. 
  22. print (loss) 
  23. Add the loss to the list  
  24. losses.append(loss) 
  25.  
  26. # Another small trick is to scale the deltas the same way as the loss function 
  27. In this way our learning rate is independent of the number of samples (observations). 
  28. # Again, this doesn't change anything in principle, it simply makes it easier to pick a single learning rate 
  29. # that can remain the same if we change the number of training samples (observations). 
  30. deltas_scaled = deltas / observations 
  31.  
  32. # Finally, we must apply the gradient descent update rules. 
  33. # The weights are 1 x 1, learning rate is 1 x 1 (scalar), inputs are 1000 x 1, and deltas_scaled are 1000 x 1 
  34. # We must transpose the inputs so that we get an allowed operation. 
  35. weights = weights - learning_rate * np.dot(x.T,deltas_scaled) 
  36. biases = biases - learning_rate * np.sum(deltas_scaled) 
  37.  
  38. # The weights are updated in a linear algebraic way (a matrix minus another matrix) 
  39. # The biases, however, are just a single number here, so we must transform the deltas into a scalar. 
  40. # The two lines are both consistent with the gradient descent methodology. 

我們可以觀察每個輪次的訓練損失。 

  1. # Plot epochs and losses 
  2. plt.plot(range(100),losses) 
  3. Add labels to x axis and y axis 
  4. plt.ylabel('loss'
  5. plt.xlabel('epoch'
  6. Add title to the graph 
  7. plt.title('Training'
  8. # Show the plot 
  9. # The curve is decreasing in each epoch, which is what we need 
  10. After several epochs, we can see that the curve is flattened. 
  11. # This means the algorithm has converged and hence there are no significant updates 
  12. or changes in the weights or biases. 
  13. plt.show() 

正如我們從圖 4 中看到的,損失在每個 epoch 中都在減少。 這意味著模型越來越接近參數的真實值。 幾個 epoch 后,損失沒有顯著變化。 這意味著模型已經收斂并且參數不再更新(或者更新非常小)。 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

此外,我們可以通過繪制實際輸出和預測輸出來驗證我們的模型在找到真實關系方面的指標。 

  1. # We print the real and predicted targets in order to see if they have a linear relationship. 
  2. # There is almost a total match between the real targets and predicted targets. 
  3. # This is a good signal of the success of our machine learning model. 
  4. plt.plot(outputs,targets, 'bo'
  5. plt.xlabel('Predicted'
  6. plt.ylabel('Real'
  7. plt.show() 
  8. # We print the weights and the biases, so we can see if they have converged to what we wanted. 
  9. # We know that the real weight is 13 and the bias is 2 
  10. print (weights, biases) 

這將生成如圖 5 所示的圖形。我們甚至可以打印最后一個 epoch 之后的參數值。 顯然,更新后的參數與實際參數非常接近。 

  1. [[13.09844702]] [1.73587336] 

 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸 

Numpy 實現線性回歸模型就是這樣。

Keras 實現

我們首先導入必要的模塊。 TensorFlow 是這個實現的核心。 它是構建模型所必需的。 Keras 是 TensorFlow 的抽象,以便于使用。 

  1. # Numpy is needed to generate the data 
  2. import numpy as np 
  3. # Matplotlib is needed for visualization 
  4. import matplotlib.pyplot as plt 
  5. # TensorFlow is needed for model build 
  6. import tensorflow as tf 

為了生成數據(特征和目標),我們使用了 Numpy 中生成數據的代碼。 我們添加了一行來將 Numpy 數組保存在一個文件中,以防我們想將它們與其他模型一起使用(可能不需要,但添加它不會有什么壞處)。 

  1. np.savez('TF_intro', inputs=x, targets=targets) 

Keras 有一個 Sequential 的類。 它用于堆疊創建模型的層。 由于我們只有一個特征和輸出,因此我們將只有一個稱為密集層的層。 這一層負責線性變換 (W*X +B),這是我們想要的模型。 該層有一個稱為神經元的計算單元用于輸出計算,因為它是一個回歸模型。 對于內核(權重)和偏置初始化,我們在給定范圍內應用了均勻隨機分布(與 Numpy 中相同,但是在層內指定)。 

  1. Declare a variable where we will store the input size of our model 
  2. # It should be equal to the number of variables you have 
  3. input_size = 1 
  4. Declare the output size of the model 
  5. # It should be equal to the number of outputs you've got (for regressions that's usually 1) 
  6. output_size = 1 
  7. # Outline the model 
  8. # We lay out the model in 'Sequential' 
  9. # Note that there are no calculations involved - we are just describing our network 
  10. model = tf.keras.Sequential([ 
  11. # Each 'layer' is listed here 
  12. # The method 'Dense' indicates, our mathematical operation to be (xw + b) 
  13. tf.keras.layers.Input(shape=(input_size , )), 
  14. tf.keras.layers.Dense(output_size, 
  15. # there are extra arguments you can include to customize your model 
  16. in our case we are just trying to create a solution that is  
  17. as close as possible to our NumPy model 
  18. # kernel here is just another name for the weight parameter 
  19. kernel_initializer=tf.random_uniform_initializer(minval=-0.1, maxval=0.1), 
  20. bias_initializer=tf.random_uniform_initializer(minval=-0.1, maxval=0.1) 
  21. ]) 
  22. # Print the structure of the model 
  23. model.summary() 

為了訓練模型,keras提供 fit 的方法可以完成這項工作。 因此,我們首先加載數據,指定特征和標簽,并設置輪次。 在訓練模型之前,我們通過選擇合適的優化器和損失函數來配置模型。 這就是 compile 的作用。 我們使用了學習率為 0.02(與之前相同)的隨機梯度下降,損失是均方誤差。 

  1. Load the training data from the NPZ 
  2. training_data = np.load('TF_intro.npz'
  3. # We can also define a custom optimizer, where we can specify the learning rate 
  4. custom_optimizer = tf.keras.optimizers.SGD(learning_rate=0.02) 
  5. 'compile' is the place where you select and indicate the optimizers and the loss 
  6. # Our loss here is the mean square error 
  7. model.compile(optimizer=custom_optimizer, loss='mse'
  8. # finally we fit the model, indicating the inputs and targets 
  9. # if they are not otherwise specified the number of epochs will be 1 (a single epoch of training),  
  10. # so the number of epochs is 'kind of' mandatory, too 
  11. # we can play around with verbose; we prefer verbose=2 
  12. model.fit(training_data['inputs'], training_data['targets'], epochs=100, verbose=2) 

我們可以在訓練期間監控每個 epoch 的損失,看看是否一切正常。 訓練完成后,我們可以打印模型的參數。 顯然,模型已經收斂了與實際值非常接近的參數值。 

  1. # Extracting the weights and biases is achieved quite easily 
  2. model.layers[0].get_weights() 
  3. # We can save the weights and biases in separate variables for easier examination 
  4. # Note that there can be hundreds or thousands of them! 
  5. weights = model.layers[0].get_weights()[0] 
  6. bias = model.layers[0].get_weights()[1] 
  7. bias,weights 
  8. (array([1.9999999], dtype=float32), array([[13.1]], dtype=float32)) 

當您構建具有數千個參數和不同層的復雜模型時,TensorFlow 可以為您節省大量精力和代碼行。 由于模型太簡單,這里并沒有顯示keras的優勢。

PyTorch 實現

我們導入 Torch。這是必須的,因為它將用于創建模型。 

  1. # Numpy is needed for data generation 
  2. import numpy as np 
  3. # Pytorch is needed for model build 
  4. import torch 

數據生成部分未顯示,因為它與前面使用的代碼相同。 但是Torch 只處理張量(torch.Tensor)。所以需要將特征和目標數組都轉換為張量。 最后,從這兩個張量創建一個張量數據集。 

  1. # TensorDataset is needed to prepare the training data in form of tensors 
  2. from torch.utils.data import TensorDataset 
  3. To run the model on either the CPU or GPU (if available) 
  4. device = 'cuda' if torch.cuda.is_available() else 'cpu' 
  5. # Since torch deals with tensors, we convert the numpy arrays into torch tensors 
  6. x_tensor = torch.from_numpy(x).float() 
  7. y_tensor = torch.from_numpy(targets).float() 
  8. # Combine the feature tensor and target tensor into torch dataset 
  9. train_data = TensorDataset(x_tensor , y_tensor) 

模型的創建很簡單。 與keras類似,Sequential 類用于創建層堆棧。 我們只有一個線性層(keras叫密集層),一個輸入和一個輸出。 模型的參數使用定義的函數隨機初始化。 為了配置模型,我們設置了學習率、損失函數和優化器。 還有其他參數需要設置,這里不做介紹。 

  1. # Initialize the seed to make the code reproducible 
  2. torch.manual_seed(42) 
  3. # This function is for model's parameters initialization 
  4. def init_weights(m): 
  5. if isinstance(m, torch.nn.Linear): 
  6. torch.nn.init.uniform_(m.weight , a = -0.1 , b = 0.1) 
  7. torch.nn.init.uniform_(m.bias , a = -0.1 , b = 0.1) 
  8. # Define the model using Sequential class 
  9. # It contains only a single linear layer with one input and one output 
  10. model = torch.nn.Sequential(torch.nn.Linear(1 , 1)).to(device) 
  11. # Initialize the model's parameters using the defined function from above 
  12. model.apply(init_weights) 
  13. # Print the model's parameters 
  14. print(model.state_dict()) 
  15. # Specify the learning rate 
  16. lr = 0.02 
  17. # The loss function is the mean squared error 
  18. loss_fn = torch.nn.MSELoss(reduction = 'mean'
  19. # The optimizer is the stochastic gradient descent with a certain learning rate 
  20. optimizer = torch.optim.SGD(model.parameters() , lr = lr) 

我們將使用小批量梯度下降訓練模型。 DataLoader 負責從訓練數據集創建批次。 訓練類似于keras的實現,但使用不同的語法。 關于 Torch訓練有幾點補充:

1- 模型和批次必須在同一設備(CPU 或 GPU)上。

2- 模型必須設置為訓練模式。

3- 始終記住在每個 epoch 之后將梯度歸零以防止累積(對 epoch 的梯度求和),這會導致錯誤的值。 

  1. # DataLoader is needed for data batching 
  2. from torch.utils.data import DataLoader 
  3. # Training dataset is converted into batches of size 16 samples each. 
  4. # Shuffling is enabled for randomizing the data 
  5. train_loader = DataLoader(train_data , batch_size = 16 , shuffle = True
  6. # A function for training the model 
  7. # It is a function of a function (How fancy) 
  8. def make_train_step(model , optimizer , loss_fn): 
  9. def train_step(x , y): 
  10. Set the model to training mode 
  11. model.train() 
  12. # Feedforward the model with the data (features) to obtain the predictions 
  13. yhat = model(x) 
  14. # Calculate the loss based on the predicted and actual targets 
  15. loss = loss_fn(y , yhat) 
  16. # Perform the backpropagation to find the gradients 
  17. loss.backward() 
  18. Update the parameters with the calculated gradients 
  19. optimizer.step() 
  20. Set the gradients to zero to prevent accumulation 
  21. optimizer.zero_grad() 
  22. return loss.item() 
  23. return train_step 
  24. # Call the training function 
  25. train_step = make_train_step(model , optimizer , loss_fn) 
  26. To store the loss of each epoch 
  27. losses = [] 
  28. Set the epochs to 100 
  29. epochs = 100 
  30. # Run the training function in each epoch on the batches of the data 
  31. # This is why we have two for loops 
  32. Outer loop for epochs 
  33. Inner loop for iterating through the training data batches 
  34. for epoch in range(epochs): 
  35. To accumulate the losses of all batches within a single epoch 
  36. batch_loss = 0 
  37. for x_batch , y_batch in train_loader: 
  38. x_batch = x_batch.to(device) 
  39. y_batch = y_batch.to(device) 
  40. loss = train_step(x_batch , y_batch) 
  41. batch_loss = batch_loss + loss 
  42. # 63 is not a magic number. It is the number of batches in the training set 
  43. # we have 1000 samples and the batch size is 16 (defined in the DataLoader) 
  44. # 1000/16 = 63 
  45. epoch_loss = batch_loss / 63 
  46. losses.append(epoch_loss) 
  47. # Print the parameters after the training is done 
  48. print(model.state_dict()) 
  49. OrderedDict([('0.weight', tensor([[13.0287]], device='cuda:0')), ('0.bias', tensor([2.0096], device='cuda:0'))]) 

作為最后一步,我們可以繪制 epoch 上的訓練損失以觀察模型的性能。 如圖 6 所示。 

初學者指南:使用 Numpy、Keras 和 PyTorch 實現最簡單的機線性回歸

完成。 讓我們總結一下到目前為止我們學到的東西。

總結 

線性回歸被認為是最容易實現和解釋的機器學習模型之一。 在本文中,我們使用 Python 中的三個不同的流行模塊實現了線性回歸。 還有其他模塊可用于創建。 例如,Scikitlearn。

責任編輯:華軒 來源: 今日頭條
相關推薦

2022-04-24 15:21:01

MarkdownHTML

2012-03-14 10:56:23

web app

2010-06-13 11:13:38

UML初學者指南

2022-07-22 13:14:57

TypeScript指南

2022-10-10 15:28:45

負載均衡

2022-03-28 09:52:42

JavaScript語言

2023-07-28 07:31:52

JavaScriptasyncawait

2021-05-10 08:50:32

網絡管理網絡網絡性能

2023-07-03 15:05:07

預測分析大數據

2022-09-05 15:36:39

Linux日志記錄syslogd

2010-08-26 15:47:09

vsftpd安裝

2018-10-28 16:14:55

Reactreact.js前端

2023-02-10 08:37:28

2023-10-16 07:04:03

2024-12-25 08:00:00

機器學習ML管道人工智能

2021-05-06 09:00:00

JavaScript靜態代碼開發

2014-04-01 10:20:00

開源Rails

2020-08-16 13:10:46

TensorFlow深度學習數據集

2024-04-28 10:56:34

Next.jsWeb應用搜索引擎優化

2023-02-19 15:31:09

架構軟件開發代碼
點贊
收藏

51CTO技術棧公眾號

黄视频在线观看网站| 欧美一区免费看| 波多野结衣欧美| 亚洲v日本v欧美v久久精品| 狠狠色伊人亚洲综合网站色| 男人天堂av在线播放| 色小子综合网| 亚洲丁香久久久| 色悠悠久久综合网| 国产在线xxx| 26uuuu精品一区二区| 国产精品青草久久久久福利99| 日本爱爱小视频| 国产一区在线电影| 欧美人牲a欧美精品| 国产www免费| 日本电影在线观看网站| 成人av网站在线观看| 国产精品久久久久久久久久久久久久 | 一本久久a久久精品vr综合 | 天堂av一区| 色偷偷久久人人79超碰人人澡| 亚洲视频导航| 瑟瑟在线观看| 国产ts人妖一区二区| 国产精品久久网| www.天天色| 亚洲乱码精品| 中文字幕精品久久| free性中国hd国语露脸| 日韩区欧美区| 在线成人av影院| 黑森林福利视频导航| 男女在线观看视频| 中文字幕亚洲在| 日产中文字幕在线精品一区| 成人免费一级视频| 精品一区二区在线视频| 国产91色在线播放| 亚洲天堂日韩av| 国模一区二区三区| 欧美xxxx做受欧美.88| 综合 欧美 亚洲日本| 精品一区在线| 精品亚洲国产成av人片传媒| 国产调教打屁股xxxx网站| 日韩福利影视| 欧美日韩日日摸| 国产又大又黄又粗的视频| 日韩伦理精品| 婷婷综合在线观看| 国产又粗又猛又爽又黄的网站| 欧美日韩欧美| 国产农村妇女精品| 欧美一区二区高清在线观看| 四虎影视精品成人| 久久亚洲二区三区| 免费在线一区二区| 全色精品综合影院| 久久视频一区二区| 欧美国产综合视频| 国产一级免费在线观看| 国产日韩欧美在线一区| 日韩一本精品| 国产精品四虎| 亚洲欧洲精品一区二区精品久久久 | 一区二区成人在线| 国产亚洲精品久久久久久久| 亚洲男同gay网站| 一区二区三区在线观看国产| 国产传媒久久久| 91九色美女在线视频| 欧美日韩在线免费观看| 国产情侣av自拍| 久久亚洲资源中文字| 91精品久久久久久久99蜜桃| 91蝌蚪视频在线| 国产厕拍一区| 亚洲欧美国内爽妇网| 久久日免费视频| 午夜精品一区二区三区国产| 欧美肥婆姓交大片| 三级黄色在线视频| 人人超碰91尤物精品国产| 成人久久精品视频| 成人午夜福利视频| 久久免费看少妇高潮| 一区二区不卡在线观看| 麻豆福利在线观看| 色屁屁一区二区| 日韩av片免费观看| 伦理一区二区三区| 日韩中文在线视频| 日韩久久久久久久久| 丝袜美腿成人在线| 91高跟黑色丝袜呻吟在线观看| 蜜臀av在线观看| 国产片一区二区| 国产免费内射又粗又爽密桃视频| 精品三级久久| 欧美日产在线观看| 岛国精品资源网站| 国产精品99一区二区三| 97色在线观看| 91精品视频免费在线观看| 成人黄色a**站在线观看| 日韩欧美一区二区三区久久婷婷| 午夜在线激情影院| 欧美在线观看视频在线| 涩视频在线观看| 日韩精品久久| 欧美孕妇与黑人孕交| 国产精品亚洲欧美在线播放| 91丨porny丨蝌蚪视频| 亚洲成年人专区| 黑人巨大亚洲一区二区久| 欧美一级二级在线观看| 亚洲精品国产91| 在线成人www免费观看视频| 国产精品极品美女在线观看免费| 免费国产黄色片| 亚洲图片激情小说| 97公开免费视频| 日韩欧美影院| 国外成人性视频| a天堂在线观看视频| 国产清纯白嫩初高生在线观看91| 麻豆tv在线播放| 亚洲福利合集| 久热精品视频在线观看| 中日精品一色哟哟| 国产日产欧美一区二区视频| 午夜免费福利小电影| 一区二区三区亚洲变态调教大结局| 日韩在线小视频| 中文字幕一区二区三区人妻四季| 91老司机福利 在线| 日韩中文字幕在线免费| 亚洲精品aⅴ| 欧美成人免费在线观看| 国产乱人乱偷精品视频a人人澡| 国产精品污www在线观看| 成年人免费大片| 国产精品日韩精品中文字幕| 91国产精品91| 天天干天天摸天天操| 亚洲国产日韩精品| 少妇极品熟妇人妻无码| 欧美三级乱码| 国产a一区二区| 欧洲一区二区三区| 精品成人佐山爱一区二区| 国产污视频在线看| jiyouzz国产精品久久| 久艹在线免费观看| 欧美变态挠脚心| 欧美在线视频导航| 国产高清视频在线| 欧美色视频在线观看| av在线免费播放网址| 精品一区二区三区免费视频| 综合一区中文字幕| 欧美第一在线视频| 97欧美精品一区二区三区| 欧美日本韩国一区二区| 91成人免费在线| 三级黄色在线观看| 国产**成人网毛片九色| 尤物av无码色av无码| 国产伦精品一区二区三区视频| 国产精品爱啪在线线免费观看| √新版天堂资源在线资源| 制服丝袜成人动漫| 国产一级淫片免费| 久久久精品影视| 91小视频网站| 国产中文一区| 精品一区二区久久久久久久网站| 欧美韩国亚洲| 成人444kkkk在线观看| 成人午夜视频一区二区播放| 欧美日韩中文字幕在线| 亚洲精品自拍视频在线观看| 成人性生交大片| 青青在线视频免费| 亚洲色图插插| 久久久久久久久久久一区| 成人免费毛片嘿嘿连载视频…| 久久影视电视剧免费网站清宫辞电视| 国精产品一品二品国精品69xx | 男女午夜激情视频| 国产大片一区| 精品欧美日韩在线| 欧美性www| 91精品国产沙发| 美女免费久久| 亚洲精品色婷婷福利天堂| 国产精品福利电影| 日韩欧美亚洲成人| 日韩a级片在线观看| 2021国产精品久久精品| xxx中文字幕| 青青青爽久久午夜综合久久午夜| 日本黄xxxxxxxxx100| 免费av一区| αv一区二区三区| 日韩一级二级| 91国产美女视频| 怡红院在线观看| 国产一区二区免费| 少妇一区二区三区四区| 777a∨成人精品桃花网| 天干夜夜爽爽日日日日| 亚洲一二三四在线观看| 国产精品久久久免费看| 久久亚洲精华国产精华液| 精品人妻在线视频| 久久99国产精品久久| 农村妇女精品一二区| 夜夜嗨一区二区| 国产在线xxxx| 欧美成人亚洲| 国产精品美女在线播放| 欧美日韩有码| 欧美日韩亚洲一区二区三区在线观看 | 欧美日韩中文字幕一区二区| 天天插天天操天天干| 亚洲一区二区三区自拍| 男女性高潮免费网站| 国产精品欧美极品| 级毛片内射视频| 91女神在线视频| 国产精品伦子伦| 成人动漫视频在线| 肉丝美足丝袜一区二区三区四| 国内不卡的二区三区中文字幕 | 99a精品视频在线观看| 91九色蝌蚪国产| 日韩欧乱色一区二区三区在线 | 精品国产一区二区三区av片| 久久精精品视频| 色婷婷狠狠五月综合天色拍 | 日韩影院二区| 亚洲不卡一卡2卡三卡4卡5卡精品| 黄色网一区二区| 国产亚洲精品美女久久久m| 91在线一区| 国产精品麻豆免费版| 久久97精品| 乱一区二区三区在线播放| 人人精品视频| 久久亚洲高清| 国产剧情一区| 在线不卡视频一区二区| 国产精品久久久久久影院8一贰佰 国产精品久久久久久麻豆一区软件 | 偷拍亚洲精品| 日韩激情视频| 日韩中文欧美| 欧美少妇在线观看| 国产精品www.| 91视频最新入口| 日韩经典中文字幕一区| 午夜两性免费视频| 国产一区二区在线电影| 波多野结衣电影免费观看| 成人av在线资源网站| aaaaa级少妇高潮大片免费看| 久久先锋影音av| www成人啪啪18软件| 亚洲欧美日韩国产中文在线| 久视频在线观看| 一本大道久久a久久精二百| 中文字幕av影视| 欧美一区二区三区免费大片| 男人天堂网在线视频| 亚洲人午夜精品| av网站在线免费看推荐| 97免费视频在线| 欧洲亚洲精品| 国产伦视频一区二区三区| 国产探花在线精品一区二区| 国产奶头好大揉着好爽视频| 精品动漫3d一区二区三区免费| 欧美激情国产精品日韩| 国内精品在线播放| 疯狂揉花蒂控制高潮h| 国产精品成人在线观看| 日韩乱码一区二区| 欧美日精品一区视频| 亚洲精品18p| 在线观看不卡av| 182在线播放| 国产欧美日韩精品专区| 国产精品调教| 国产高清免费在线| 久久婷婷一区| 午夜性福利视频| 国产精品激情偷乱一区二区∴| 精品小视频在线观看| 欧美私模裸体表演在线观看| 蜜臀av免费在线观看| xxxxx91麻豆| 欧美xoxoxo| 国产高清在线一区二区| 日韩成人精品一区| 国产在线青青草| 成人丝袜视频网| 免费成人深夜夜行网站| 91国产免费看| 无码精品人妻一区二区| 美日韩丰满少妇在线观看| 欧美黄色三级| 久久久7777| 国产精品大片| 亚洲黄色av片| 日本一区二区成人| av大片在线免费观看| 日韩一卡二卡三卡国产欧美| av网页在线| 国产成人精品a视频一区www| 老牛影视av一区二区在线观看| 99热这里只有精品7| 欧美a级理论片| 午夜理伦三级做爰电影| 亚洲va天堂va国产va久| 午夜精品一二三区| 两个人的视频www国产精品| 久久69成人| 色综合久久88色综合天天提莫| 亚洲一区区二区| 亚洲黄色免费在线观看| 亚洲一区在线观看免费 | 国产99久久久精品| 国产suv精品一区二区68| 欧美色综合久久| 国产精品一级伦理| 日本一区二区不卡| 天海翼亚洲一区二区三区| 日本www在线视频| www.av精品| 天天干天天干天天| 亚洲精品在线91| 韩国主播福利视频一区二区三区| 久久亚洲综合网| 久久永久免费| 人妻视频一区二区| 欧美在线免费播放| 天堂а√在线资源在线| 国产欧美日韩精品专区| 五月婷婷亚洲| 手机精品视频在线| 亚洲午夜激情网站| 全部免费毛片在线播放一个| 亚洲91精品在线| 色爱综合av| 久久婷婷国产91天堂综合精品| 久久久精品综合| 中文字幕在线观看国产| 久久久国产一区二区三区| 国产一精品一av一免费爽爽| avove在线观看| 成人听书哪个软件好| 国产精品一区二区6| 亚洲男人天堂久| 国产精品66| 国内精品国产三级国产99| 豆国产96在线|亚洲| 粉嫩aⅴ一区二区三区| 亚洲欧洲av一区二区| 国产黄色一区| 精品成在人线av无码免费看| 99视频精品在线| 国产成人无码专区| 美日韩精品免费视频| 成人自拍在线| av无码精品一区二区三区| 国产精品美女久久福利网站| 99热这里只有精品在线| 91国在线精品国内播放| 欧美色图激情小说| 在线视频观看一区二区| 亚洲第一激情av| melody高清在线观看| 18成人在线| 亚洲自拍另类| 麻豆视频在线免费看| 日韩大片在线观看视频| 九九久久国产| 男人日女人视频网站| 中文字幕欧美激情一区| 丰满人妻一区二区三区免费视频| 欧美一级电影免费在线观看| 久久在线免费| 精品人妻伦一二三区久| 精品视频一区三区九区| 麻豆蜜桃在线| 偷拍盗摄高潮叫床对白清晰| 91色视频在线| 国产女主播福利| 国产精品1234|