<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí)

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 19:26:36
        文檔

        基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí)

        基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí):本篇文章講述的是基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí),具有一定參考價值,感興趣的朋友可以了解一下。雖然python或r編程語言有一個相對容易的學(xué)習(xí)曲線,但是Web開發(fā)人員更喜歡在他們舒適的javascript區(qū)域內(nèi)做事情。目前來看,node.js已經(jīng)開始向每
        推薦度:
        導(dǎo)讀基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí):本篇文章講述的是基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí),具有一定參考價值,感興趣的朋友可以了解一下。雖然python或r編程語言有一個相對容易的學(xué)習(xí)曲線,但是Web開發(fā)人員更喜歡在他們舒適的javascript區(qū)域內(nèi)做事情。目前來看,node.js已經(jīng)開始向每
        本篇文章講述的是基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí),具有一定參考價值,感興趣的朋友可以了解一下。

        2509688-34b48c580d89eae1.png

        雖然python或r編程語言有一個相對容易的學(xué)習(xí)曲線,但是Web開發(fā)人員更喜歡在他們舒適的javascript區(qū)域內(nèi)做事情。目前來看,node.js已經(jīng)開始向每個領(lǐng)域應(yīng)用javascript,在這一大趨勢下我們需要理解并使用JS進(jìn)行機(jī)器學(xué)習(xí)。由于可用的軟件包數(shù)量眾多,python變得流行起來,但是JS社區(qū)也緊隨其后。這篇文章會幫助初學(xué)者學(xué)習(xí)如何構(gòu)建一個簡單的分類器。

        創(chuàng)建

        我們可以創(chuàng)建一個使用tensorflow.js在瀏覽器中訓(xùn)練模型的網(wǎng)頁。考慮到房屋的“avgareanumberofrows”,模型可以學(xué)習(xí)去預(yù)測房屋的“價格”。

        為此我們要做的是:

        加載數(shù)據(jù)并為培訓(xùn)做好準(zhǔn)備。

        定義模型的體系結(jié)構(gòu)。

        訓(xùn)練模型并在訓(xùn)練時監(jiān)控其性能。

        通過做出一些預(yù)測來評估經(jīng)過訓(xùn)練的模型。

        第一步:讓我們從基礎(chǔ)開始

        創(chuàng)建一個HTML頁面并包含JavaScript。將以下代碼復(fù)制到名為index.html的HTML文件中。

        <!DOCTYPE html>
        <html>
        <head>
         <title>TensorFlow.js Tutorial</title>
         <!-- Import TensorFlow.js -->
         <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
         <!-- Import tfjs-vis -->
         <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
         <!-- Import the main script file -->
         <script src="script.js"></script>
        </head>
        <body>
        </body>
        </html>

        為代碼創(chuàng)建javascript文件

        在與上面的HTML文件相同的文件夾中,創(chuàng)建一個名為script.js的文件,并將以下代碼放入其中。

        console.log('Hello TensorFlow');

        測試

        既然已經(jīng)創(chuàng)建了HTML和JavaScript文件,那么就測試一下它們。在瀏覽器中打開index.html文件并打開devtools控制臺。

        如果一切正常,那么應(yīng)該在devtools控制臺中創(chuàng)建并可用兩個全局變量:

      1. tf是對tensorflow.js庫的引用
      2. tfvis是對tfjs vis庫的引用
      3. 現(xiàn)在你應(yīng)該可以看到一條消息,上面寫著“Hello TensorFlow”。如果是這樣,你就可以繼續(xù)下一步了。

        2509688-58c8cca77a857ae2.png

        注意:可以使用Bit來共享可重用的JS代碼

        Bit(GitHub上的Bit)是跨項(xiàng)目和應(yīng)用程序共享可重用JavaScript代碼的最快和最可擴(kuò)展的方式??梢栽囈辉?,它是免費(fèi)的:

        組件發(fā)現(xiàn)與協(xié)作·Bit

        Bit是開發(fā)人員共享組件和協(xié)作,共同構(gòu)建令人驚嘆的軟件的地方。發(fā)現(xiàn)共享的組件…
        Bit.dev

        例如:Ramda用作共享組件

        Ramda by Ramda·Bit

        一個用于JavaScript程序員的實(shí)用函數(shù)庫。-256個javascript組件。例如:等號,乘…
        Bit.dev

        第2步:加載數(shù)據(jù),格式化數(shù)據(jù)并可視化輸入數(shù)據(jù)

        我們將加載“house”數(shù)據(jù)集,可以在這里找到。它包含了特定房子的許多不同特征。對于本教程,我們只需要有關(guān)房間平均面積和每套房子價格的數(shù)據(jù)。

        將以下代碼添加到script.js文件中。

        async function getData() {
         Const houseDataReq=await
        fetch('https://raw.githubusercontent.com/meetnandu05/ml1/master/house.json'); 
         const houseData = await houseDataReq.json(); 
         const cleaned = houseData.map(house => ({
         price: house.Price,
         rooms: house.AvgAreaNumberofRooms,
         }))
         .filter(house => (house.price != null && house.rooms != null));
        
         return cleaned;
        }

        這可以刪除沒有定義價格或房間數(shù)量的任何條目。我們可以將這些數(shù)據(jù)繪制成散點(diǎn)圖,看看它是什么樣子的。

        將以下代碼添加到script.js文件的底部。

        async function run() {
         // Load and plot the original input data that we are going to train on.
         const data = await getData();
         const values = data.map(d => ({
         x: d.rooms,
         y: d.price,
         }));
         tfvis.render.scatterplot(
         {name: 'No.of rooms v Price'},
         {values}, 
         {
         xLabel: 'No. of rooms',
         yLabel: 'Price',
         height: 300
         }
         );
         // More code will be added below
        }
        document.addEventListener('DOMContentLoaded', run);

        刷新頁面時,你可以在頁面左側(cè)看到一個面板,上面有數(shù)據(jù)的散點(diǎn)圖,如下圖。

        2509688-b720e94c2cbd9ed2.png

        通常,在處理數(shù)據(jù)時,最好找到方法來查看數(shù)據(jù),并在必要時對其進(jìn)行清理。可視化數(shù)據(jù)可以讓我們了解模型是否可以學(xué)習(xí)數(shù)據(jù)的任何結(jié)構(gòu)。

        從上面的圖中可以看出,房間數(shù)量與價格之間存在正相關(guān)關(guān)系,即隨著房間數(shù)量的增加,房屋價格普遍上漲。

        第三步:建立待培訓(xùn)的模型

        這一步我們將編寫代碼來構(gòu)建機(jī)器學(xué)習(xí)模型。模型主要基于此代碼進(jìn)行架構(gòu),所以這是一個比較重要的步驟。機(jī)器學(xué)習(xí)模型接受輸入,然后產(chǎn)生輸出。對于tensorflow.js,我們必須構(gòu)建神經(jīng)網(wǎng)絡(luò)。

        將以下函數(shù)添加到script.js文件中以定義模型。

        function createModel() {
         // Create a sequential model
         const model = tf.sequential(); 
        
         // Add a single hidden layer
         model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));
        
         // Add an output layer
         model.add(tf.layers.dense({units: 1, useBias: true}));
         return model;
        }

        這是我們可以在tensorflow.js中定義的最簡單的模型之一,我們來試下簡單分解每一行。

        實(shí)例化模型

        const model = tf.sequential();

        這將實(shí)例化一個tf.model對象。這個模型是連續(xù)的,因?yàn)樗妮斎胫苯恿飨蛩?/script>輸出。其他類型的模型可以有分支,甚至可以有多個輸入和輸出,但在許多情況下,你的模型是連續(xù)的。

        添加層

        model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));

        這為我們的網(wǎng)絡(luò)添加了一個隱藏層。因?yàn)檫@是網(wǎng)絡(luò)的第一層,所以我們需要定義我們的輸入形狀。輸入形狀是[1],因?yàn)槲覀冇?這個數(shù)字作為輸入(給定房間的房間數(shù))。

        單位(鏈接)設(shè)置權(quán)重矩陣在層中的大小。在這里將其設(shè)置為1,我們可以說每個數(shù)據(jù)輸入特性都有一個權(quán)重。

        model.add(tf.layers.dense({units: 1}));

        上面的代碼創(chuàng)建了我們的輸出層。我們將單位設(shè)置為1,因?yàn)槲覀円?/script>輸出1這個數(shù)字。

        創(chuàng)建實(shí)例

        將以下代碼添加到前面定義的運(yùn)行函數(shù)中。

        // Create the model
        const model = createModel(); 
        tfvis.show.modelSummary({name: 'Model Summary'}, model);

        這樣可以創(chuàng)建實(shí)例模型,并且在網(wǎng)頁上有顯示層的摘要。

        2509688-00655eb089d38a29.png

        步驟4:為創(chuàng)建準(zhǔn)備數(shù)據(jù)

        為了獲得TensorFlow.js的性能優(yōu)勢,使培訓(xùn)機(jī)器學(xué)習(xí)模型實(shí)用化,我們需要將數(shù)據(jù)轉(zhuǎn)換為Tensors。

        將以下代碼添加到script.js文件中。

        function convertToTensor(data) {
        
         return tf.tidy(() => {
         // Step 1\. Shuffle the data 
         tf.util.shuffle(data);
         // Step 2\. Convert data to Tensor
         const inputs = data.map(d => d.rooms)
         const labels = data.map(d => d.price);
         const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
         const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
         //Step 3\. Normalize the data to the range 0 - 1 using min-max scaling
         const inputMax = inputTensor.max();
         const inputMin = inputTensor.min(); 
         const labelMax = labelTensor.max();
         const labelMin = labelTensor.min();
         const normalizedInputs = inputTensor.sub(inputMin).p(inputMax.sub(inputMin));
         const normalizedLabels = labelTensor.sub(labelMin).p(labelMax.sub(labelMin));
         return {
         inputs: normalizedInputs,
         labels: normalizedLabels,
         // Return the min/max bounds so we can use them later.
         inputMax,
         inputMin,
         labelMax,
         labelMin,
         }
         }); 
        }

        接下來,我們可以分析一下將會出現(xiàn)什么情況。

        隨機(jī)播放數(shù)據(jù)

        // Step 1\. Shuffle the data 
        tf.util.shuffle(data);

        在訓(xùn)練模型的過程中,數(shù)據(jù)集被分成更小的集合,每個集合稱為一個批。然后將這些批次送入模型運(yùn)行。整理數(shù)據(jù)很重要,因?yàn)槟P筒粦?yīng)該一次又一次地得到相同的數(shù)據(jù)。如果模型一次又一次地得到相同的數(shù)據(jù),那么模型將無法歸納數(shù)據(jù),并為運(yùn)行期間收到的輸入提供指定的輸出。洗牌將有助于在每個批次中擁有各種數(shù)據(jù)。

        轉(zhuǎn)換為Tensor

        // Step 2\. Convert data to Tensor
        const inputs = data.map(d => d.rooms)
        const labels = data.map(d => d.price);
        const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
        const labelTensor = tf.tensor2d(labels, [labels.length, 1]);

        這里我們制作了兩個數(shù)組,一個用于輸入示例(房間條目數(shù)),另一個用于實(shí)際輸出值(在機(jī)器學(xué)習(xí)中稱為標(biāo)簽,在我們的例子中是每個房子的價格)。然后我們將每個數(shù)組數(shù)據(jù)轉(zhuǎn)換為一個二維張量。

        規(guī)范化數(shù)據(jù)

        //Step 3\. Normalize the data to the range 0 - 1 using min-max scaling
        const inputMax = inputTensor.max();
        const inputMin = inputTensor.min(); 
        const labelMax = labelTensor.max();
        const labelMin = labelTensor.min();
        const normalizedInputs = inputTensor.sub(inputMin).p(inputMax.sub(inputMin));
        const normalizedLabels = labelTensor.sub(labelMin).p(labelMax.sub(labelMin));

        接下來,我們規(guī)范化數(shù)據(jù)。在這里,我們使用最小-最大比例將數(shù)據(jù)規(guī)范化為數(shù)值范圍0-1。規(guī)范化很重要,因?yàn)槟鷮⑹褂胻ensorflow.js構(gòu)建的許多機(jī)器學(xué)習(xí)模型的內(nèi)部設(shè)計(jì)都是為了使用不太大的數(shù)字。規(guī)范化數(shù)據(jù)以包括0到1或-1到1的公共范圍。

        返回數(shù)據(jù)和規(guī)范化界限

        return {
         inputs: normalizedInputs,
         labels: normalizedLabels,
         // Return the min/max bounds so we can use them later.
         inputMax,
         inputMin,
         labelMax,
         labelMin,
        }

        我們可以在運(yùn)行期間保留用于標(biāo)準(zhǔn)化的值,這樣我們就可以取消標(biāo)準(zhǔn)化輸出,使其恢復(fù)到原始規(guī)模,我們就可以用同樣的方式規(guī)范化未來的輸入數(shù)據(jù)。

        步驟5:運(yùn)行模型

        通過創(chuàng)建模型實(shí)例、將數(shù)據(jù)表示為張量,我們可以準(zhǔn)備開始運(yùn)行模型。

        將以下函數(shù)復(fù)制到script.js文件中。

        async function trainModel(model, inputs, labels) {
         // Prepare the model for training. 
         model.compile({
         optimizer: tf.train.adam(),
         loss: tf.losses.meanSquaredError,
         metrics: ['mse'],
         });
        
         const batchSize = 28;
         const epochs = 50;
        
         return await model.fit(inputs, labels, {
         batchSize,
         epochs,
         shuffle: true,
         callbacks: tfvis.show.fitCallbacks(
         { name: 'Training Performance' },
         ['loss', 'mse'], 
         { height: 200, callbacks: ['onEpochEnd'] }
         )
         });
        }

        我們把它分解一下。

        準(zhǔn)備運(yùn)行

        // Prepare the model for training. 
        model.compile({
         optimizer: tf.train.adam(),
         loss: tf.losses.meanSquaredError,
         metrics: ['mse'],
        });

        我們必須在訓(xùn)練前“編譯”模型。要做到這一點(diǎn),我們必須明確一些非常重要的事情:

        優(yōu)化器:這是一個算法,它可以控制模型的更新,就像上面看到的例子一樣。TensorFlow.js中有許多可用的優(yōu)化器。這里我們選擇了Adam優(yōu)化器,因?yàn)樗趯?shí)踐中非常有效,不需要進(jìn)行額外配置。

        損失函數(shù):這是一個函數(shù),它用于檢測模型所顯示的每個批(數(shù)據(jù)子集)方面完成的情況如何。在這里,我們可以使用meansquaredrror將模型所做的預(yù)測與真實(shí)值進(jìn)行比較。

        度量:這是我們要在每個區(qū)塊結(jié)束時用來計(jì)算的度量數(shù)組。我們可以用它計(jì)算整個訓(xùn)練集的準(zhǔn)確度,這樣我們就可以檢查自己的運(yùn)行結(jié)果了。這里我們使用mse,它是meansquaredrror的簡寫。這是我們用于損失函數(shù)的相同函數(shù),也是回歸任務(wù)中常用的函數(shù)。

        const batchSize = 28;
        const epochs = 50;

        接下來,我們選擇一個批量大小和一些時間段:

        batchSize指的是模型在每次運(yùn)行迭代時將看到的數(shù)據(jù)子集的大小。常見的批量大小通常在32-512之間。對于所有問題來說,并沒有一個真正理想的批量大小,描述各種批量大小的精確方式這一知識點(diǎn)本教程沒有相關(guān)講解,對這些有興趣可以通過別的渠道進(jìn)行了解學(xué)習(xí)。

        epochs指的是模型將查看你提供的整個數(shù)據(jù)集的次數(shù)。在這里,我們通過數(shù)據(jù)集進(jìn)行50次迭代。

        啟動列車環(huán)路

        return model.fit(inputs, labels, {
         batchSize,
         epochs,
         callbacks: tfvis.show.fitCallbacks(
         { name: 'Training Performance' },
         ['loss', 'mse'], 
         { 
         height: 200, 
         callbacks: ['onEpochEnd']
         }
         )
        });

        model.fit是我們調(diào)用的啟動循環(huán)的函數(shù)。它是一個異步函數(shù),因此我們返回它給我們的特定值,以便調(diào)用者可以確定運(yùn)行結(jié)束時間。

        為了監(jiān)控運(yùn)行進(jìn)度,我們將一些回調(diào)傳遞給model.fit。我們使用tfvis.show.fitcallbacks生成函數(shù),這些函數(shù)可以為前面指定的“損失”和“毫秒”度量繪制圖表。

        把它們放在一起

        現(xiàn)在我們必須調(diào)用從運(yùn)行函數(shù)定義的函數(shù)。

        將以下代碼添加到運(yùn)行函數(shù)的底部。

        // Convert the data to a form we can use for training.
        const tensorData = convertToTensor(data);
        const {inputs, labels} = tensorData;
        
        // Train the model 
        await trainModel(model, inputs, labels);
        console.log('Done Training');

        刷新頁面時,幾秒鐘后,你應(yīng)該會看到圖形正在更新。

        這些是由我們之前創(chuàng)建的回調(diào)創(chuàng)建的。它們在每個時代結(jié)束時顯示丟失(在最近的批處理上)和毫秒(在整個數(shù)據(jù)集上)。

        當(dāng)訓(xùn)練一個模型時,我們希望看到損失減少。在這種情況下,因?yàn)槲覀兊亩攘渴且粋€誤差度量,所以我們希望看到它也下降。

        第6步:做出預(yù)測

        既然我們的模型經(jīng)過了訓(xùn)練,我們想做一些預(yù)測。讓我們通過觀察它預(yù)測的低到高數(shù)量房間的統(tǒng)一范圍來評估模型。

        將以下函數(shù)添加到script.js文件中

        function testModel(model, inputData, normalizationData) {
         const {inputMax, inputMin, labelMin, labelMax} = normalizationData; 
        
         // Generate predictions for a uniform range of numbers between 0 and 1;
         // We un-normalize the data by doing the inverse of the min-max scaling 
         // that we did earlier.
         const [xs, preds] = tf.tidy(() => {
        
         const xs = tf.linspace(0, 1, 100); 
         const preds = model.predict(xs.reshape([100, 1])); 
        
         const unNormXs = xs
         .mul(inputMax.sub(inputMin))
         .add(inputMin);
        
         const unNormPreds = preds
         .mul(labelMax.sub(labelMin))
         .add(labelMin);
        
         // Un-normalize the data
         return [unNormXs.dataSync(), unNormPreds.dataSync()];
         });
        
         const predictedPoints = Array.from(xs).map((val, i) => {
         return {x: val, y: preds[i]}
         });
        
         const originalPoints = inputData.map(d => ({
         x: d.rooms, y: d.price,
         }));
        
         tfvis.render.scatterplot(
         {name: 'Model Predictions vs Original Data'}, 
         {values: [originalPoints, predictedPoints], series: ['original', 'predicted']}, 
         {
         xLabel: 'No. of rooms',
         yLabel: 'Price',
         height: 300
         }
         );
        }

        在上面的函數(shù)中需要注意的一些事情。

        const xs = tf.linspace(0, 1, 100); 
        const preds = model.predict(xs.reshape([100, 1]));

        我們生成100個新的“示例”以提供給模型。model.predict是我們?nèi)绾螌⑦@些示例輸入到模型中的。注意,他們需要有一個類似的形狀([num_的例子,num_的特點(diǎn)每個_的例子])當(dāng)我們做培訓(xùn)時。

        // Un-normalize the data
        const unNormXs = xs
         .mul(inputMax.sub(inputMin))
         .add(inputMin);
        
        const unNormPreds = preds
         .mul(labelMax.sub(labelMin))
         .add(labelMin);

        為了將數(shù)據(jù)恢復(fù)到原始范圍(而不是0–1),我們使用規(guī)范化時計(jì)算的值,但只需反轉(zhuǎn)操作。

        return [unNormXs.dataSync(), unNormPreds.dataSync()];

        .datasync()是一種方法,我們可以使用它來獲取存儲在張量中的值的typedarray。這允許我們在常規(guī)的javascript中處理這些值。這是通常首選的.data()方法的同步版本。

        最后,我們使用tfjs-vis來繪制原始數(shù)據(jù)和模型中的預(yù)測。

        將以下代碼添加到運(yùn)行函數(shù)中。

        testModel(model, data, tensorData);

        刷新頁面,現(xiàn)在已經(jīng)完成啦!

        現(xiàn)在你已經(jīng)學(xué)會使用tensorflow.js創(chuàng)建一個簡單的機(jī)器學(xué)習(xí)模型了。

        相關(guān)教程:JavaScript視頻教程

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí)

        基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí):本篇文章講述的是基于TensorFlow.js的JavaScript機(jī)器學(xué)習(xí),具有一定參考價值,感興趣的朋友可以了解一下。雖然python或r編程語言有一個相對容易的學(xué)習(xí)曲線,但是Web開發(fā)人員更喜歡在他們舒適的javascript區(qū)域內(nèi)做事情。目前來看,node.js已經(jīng)開始向每
        推薦度:
        標(biāo)簽: js javascript 基于
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲欧美不卡高清在线| 亚洲国产日韩在线| 免费毛片毛片网址| 亚洲国产V高清在线观看| 人人爽人人爽人人片A免费| 高清在线亚洲精品国产二区| 日韩毛片在线免费观看| 91麻豆精品国产自产在线观看亚洲| 免费播放美女一级毛片| 亚洲一区二区三区乱码A| 中文字幕无线码免费人妻| 亚洲AV无码成人精品区蜜桃| 精品无码人妻一区二区免费蜜桃| 亚洲综合一区二区| 麻豆国产入口在线观看免费| 又长又大又粗又硬3p免费视频| 亚洲高清无码在线观看| 免费av片在线观看网站| 亚洲一区二区三区亚瑟 | 无码乱人伦一区二区亚洲| 久久99精品视免费看| 亚洲国产av高清无码| 小小影视日本动漫观看免费| 国产乱子伦精品免费视频| 亚洲国产高清人在线| 久久久久国色AV免费观看性色| 精品国产亚洲一区二区三区在线观看 | 97免费人妻无码视频| 亚洲爆乳精品无码一区二区| 亚洲美女高清一区二区三区| 蜜桃视频在线观看免费视频网站WWW| 亚洲高清有码中文字| 国产亚洲AV手机在线观看 | 怡红院免费的全部视频| 亚洲人成激情在线播放| 亚洲精品专区在线观看| 2021精品国产品免费观看| 亚洲日韩在线中文字幕综合| 久久久久久亚洲精品| 国产大片51精品免费观看| 先锋影音资源片午夜在线观看视频免费播放|