国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

泛化&泛化數據集&實驗

SimpleTriangle / 2331人閱讀

摘要:泛化泛化數據集實驗泛化過擬合的風險泛化泛化能力是指機器學習算法對新鮮樣本的適應能力。機器學習的基本沖突是適當擬合我們的數據,但也要盡可能簡單地擬合數據。使用測試集再次檢查該模型。特征通常在正常范圍內,其中第百分位數的值約為。

泛化&泛化數據集&實驗 泛化 (Generalization):過擬合的風險

泛化:泛化能力(generalization ability)是指機器學習算法對新鮮樣本的適應能力。學習的目的是學到隱含在數據對背后的規律,對具有同一規律的學習集以外的數據,經過訓練的網絡也能給出合適的輸出,該能力稱為泛化能力。

前兩篇實現了線性回歸模型得訓練,并再最后進行了采用合成特征作為特征輸入,且過濾了離群值,效果似乎不錯,但是這個不錯的結果來自于我們采用了原來的訓練數據進行的測試,這樣的評估意義大嗎?如果我們使用了新的(訓練模型從未遇見過的)數據進行預測,得到的結果可能會不敬人意。
假設我對模型不斷的進行訓練,不斷調整超參數,經過若干天后,得到的模型能夠達到完美的預測效果,對于輸入的任意特征都能得到正確的target,但是這并不是我們想要的模型,因為其只達到了對訓練數據的完美貼合,但并不一定能對它從未見過的新數據做出正確的預測,并且其訓練了過久,模型也會變的過于復雜,這樣就叫做過擬合

大概過程如下圖(圖片來源于谷歌機器學習樣圖):
為了讓您直觀地理解這一概念,我們將展示 3 張圖。假設這些圖中的每個點代表一棵樹在森林中的位置。圖中的兩種顏色分別代表以下含義:

藍點代表生病的樹。

橙點代表健康的樹。

圖 1. 生病(藍色)和健康(橙色)的樹。

您能設想出一個有效的模型來預測以后的生病或健康的樹嗎?花點時間在腦海里繪制一條弧線將藍點與橙點分開,或者在腦海中圈住一些橙點或藍點。然后再看看圖 2,它顯示某種機器學習模型如何將生病的樹與健康的樹區分開。請注意,該模型產生的損失非常低。

圖 2. 用于區分生病的樹與健康的樹的復雜模型。
乍一看,圖 2 所示的模型在將健康的樹與生病的樹區分開方面似乎表現得非常出色。真的是這樣嗎?

圖 3. 該模型在預測新數據方面表現非常糟糕。
圖 3 顯示我們向該模型中添加了新數據后所發生的情況。結果表明,該模型在處理新數據方面表現非常糟糕。請注意,該模型對大部分新數據的分類都不正確。


圖 2 和圖 3 所示的模型過擬合了訓練數據的特性。過擬合模型在訓練過程中產生的損失很低,但在預測新數據方面的表現卻非常糟糕。如果某個模型在擬合當前樣本方面表現良好,那么我們如何相信該模型會對新數據做出良好的預測呢?正如您稍后將看到的,過擬合是由于模型的復雜程度超出所需程度而造成的。機器學習的基本沖突是適當擬合我們的數據,但也要盡可能簡單地擬合數據。

一種解決方法是將您的數據集分成兩個子集:

訓練集 - 用于訓練模型的子集。

測試集 - 用于測試模型的子集。

一般來說,在-測試集上表現是否良好是衡量能否在新數據上表現良好的有用指標,前提是:

測試集足夠大。

不會反復使用相同的測試集來作假。

我們從分布中隨機抽取樣本,且這些樣本是獨立同分布 (i.i.d) 的

獨立同分布:1、每次抽取是隨機的,不被其他條件所約束 2、所抽取的樣本是同分布的,即滿足同一個分布規律(如,抽紙牌,得從同樣得一副牌中抽取)3、分布是平穩的,即分布在數據集內不會發生變化

接下來我們來談談訓練集測試集

訓練集和測試集 (Training and Test Sets):拆分數據

訓練集 - 用于訓練模型的子集。

測試集 - 用于測試訓練后模型的子集

如果我們只有一個數據集,但是需要訓練集測試集,辦法很簡單,拆分就好了,比例大概可以是4:1這樣子

不過,拆分數據時候得遵循幾個原則
1.數據集夠大
2.隨機抽取的,能代表數據集的水平

注意請勿對測試數據進行訓練,如果最后測試得到的結果意外的好,那最好檢查一下,多數是因為對測試數據進行了誤訓練

這是我們剛才討論的劃分方式--訓練集和測試集

但是這樣的劃分方式,會不會有問題呢?如果為了在最后的測試數據上獲得最佳效果,從而更改學習速率、添加或移除特征,到從頭開始設計全新模型。當該工作流程結束時,在測試數據上表現很好,那么最終依然很有可能是過擬合的。

所以我們可以進一步劃分,即訓練集+驗證集合+測試集合

在這一經過改進的工作流程中:

選擇在驗證集上獲得最佳效果的模型。

使用測試集再次檢查該模型。

該工作流程之所以更好,原因在于它暴露給測試集的信息更少

接下來,我們將對之前的理論進行驗證

驗證

使用多個特征而非單個特征來進一步提高模型的有效性

調試模型輸入數據中的問題

使用測試數據集檢查模型是否過擬合驗證數據


與在之前的練習中一樣,我們將依然使用加利福尼亞州住房數據集,嘗試根據 1990 年的人口普查數據在城市街區級別預測 median_house_value

設置和測試

我們首先加載并準備數據。這一次,我們將使用多個特征,因此我們會將邏輯模塊化,以對特征進行預處理:


import math

from IPython import display
from matplotlib import cm
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
from sklearn import metrics
import tensorflow as tf
from tensorflow.python.data import Dataset

tf.logging.set_verbosity(tf.logging.ERROR)
pd.options.display.max_rows = 10
pd.options.display.float_format = "{:.1f}".format

california_housing_dataframe = pd.read_csv("https://storage.googleapis.com/mledu-datasets/california_housing_train.csv", sep=",")

# california_housing_dataframe = california_housing_dataframe.reindex(
#     np.random.permutation(california_housing_dataframe.index))

# 對特征預處理
def preprocess_features(california_housing_dataframe):
  selected_features = california_housing_dataframe[
    ["latitude",
     "longitude",
     "housing_median_age",
     "total_rooms",
     "total_bedrooms",
     "population",
     "households",
     "median_income"]]
  processed_features = selected_features.copy()
  # 此外多創建一個合成特征
  processed_features["rooms_per_person"] = (
    california_housing_dataframe["total_rooms"] /
    california_housing_dataframe["population"])
  return processed_features
# 對target預處理
def preprocess_targets(california_housing_dataframe):
# output_targets為pd.DataFrame()類型的數據結構(這種結構類似于表格,有行有列的索引)
  output_targets = pd.DataFrame()
  output_targets["median_house_value"] = (
    california_housing_dataframe["median_house_value"] / 1000.0)
  return output_targets

# 訓練集取前12000(共17000樣本)
training_examples = preprocess_features(california_housing_dataframe.head(12000))
training_examples.describe()
latitude longitude housing_median_age total_rooms total_bedrooms population households median_income rooms_per_person
count 12000.0 12000.0 12000.0 12000.0 12000.0 12000.0 12000.0 12000.0 12000.0
mean 34.6 -118.5 27.5 2655.7 547.1 1476.0 505.4 3.8 1.9
std 1.6 1.2 12.1 2258.1 434.3 1174.3 391.7 1.9 1.3
min 32.5 -121.4 1.0 2.0 2.0 3.0 2.0 0.5 0.0
25% 33.8 -118.9 17.0 1451.8 299.0 815.0 283.0 2.5 1.4
50% 34.0 -118.2 28.0 2113.5 438.0 1207.0 411.0 3.5 1.9
75% 34.4 -117.8 36.0 3146.0 653.0 1777.0 606.0 4.6 2.3
max 41.8 -114.3 52.0 37937.0 5471.0 35682.0 5189.0 15.0 55.2
training_targets = preprocess_targets(california_housing_dataframe.head(12000))
training_targets.describe()
median_house_value
count 12000.0
mean 198.0
std 111.9
min 15.0
25% 117.1
50% 170.5
75% 244.4
max 500.0
# 測試集取尾5000
validation_examples = preprocess_features(california_housing_dataframe.tail(5000))
validation_examples.describe()
latitude longitude housing_median_age total_rooms total_bedrooms population households median_income rooms_per_person
count 5000.0 5000.0 5000.0 5000.0 5000.0 5000.0 5000.0 5000.0 5000.0
mean 38.1 -122.2 31.3 2614.8 521.1 1318.1 491.2 4.1 2.1
std 0.9 0.5 13.4 1979.6 388.5 1073.7 366.5 2.0 0.6
min 36.1 -124.3 1.0 8.0 1.0 8.0 1.0 0.5 0.1
25% 37.5 -122.4 20.0 1481.0 292.0 731.0 278.0 2.7 1.7
50% 37.8 -122.1 31.0 2164.0 424.0 1074.0 403.0 3.7 2.1
75% 38.4 -121.9 42.0 3161.2 635.0 1590.2 603.0 5.1 2.4
max 42.0 -121.4 52.0 32627.0 6445.0 28566.0 6082.0 15.0 18.3
validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))
validation_targets.describe()
median_house_value
count 5000.0
mean 229.5
std 122.5
min 15.0
25% 130.4
50% 213.0
75% 303.2
max 500.0

在上面我們是把數據集中除了median_house_value作為target外,其他得所有列都作為了feature輸入
我們雖然沒有什么數據分析或者統計學得背景知識,但是其實還是可以看一看,或者說猜一猜輸入的這些特征到底是些什么,它們可能具有哪些意義?取值范圍是怎么樣的,數值的大小正常嘛?等等等

latitude:緯度
longitude:經度
housing_median_age:房子年紀(中值)
total_rooms:房間總數(每個街區)
total_bedrooms:臥室總數(每個街區)
total_bedrooms:人口數(每個街區)
households:戶(一家人為一戶)
median_income :收入(中值)

再看看這些feature的數值(最大值,最小值),理解一下它們的單位(當然,會有不合理的,因為存在數據比較特殊,而且這是1990年的數據了),這些數據會幫助我們在宏觀上了解這些數據集,特別是一旦發現不合理的地方更是要注意了(尤其在訓練自己的數據時)

異常情況:

median_income 位于 3 到 15 的范圍內。我們完全不清楚此范圍究竟指的是什么,看起來可能是某對數尺度?無法找到相關記錄;我們所能假設的只是,值越高,相應的收入越高。

median_house_value 的最大值是 500001。這看起來像是某種人為設定的上限。

rooms_per_person 特征通常在正常范圍內,其中第 75 百分位數的值約為 2。但也有一些非常大的值(例如 18 或 55),這可能表明數據有一定程度的損壞。

我們將暫時使用提供的這些特征。但希望這些示例可幫助您較為直觀地了解如何檢查來自未知來源的數據

### 繪制緯度/經度與房屋價值中位數的曲線圖

*

我們來詳細了解一下 latitudelongitude 這兩個特征。它們是相關城市街區的地理坐標。

利用這兩個特征可以提供出色的可視化結果 - 我們來繪制 latitudelongitude 的曲線圖,然后用顏色標注 median_house_value

plt.figure(figsize=(13, 8))

ax = plt.subplot(1, 2, 1)
ax.set_title("Validation Data")

# 取消y軸的自動縮放,并定義上下限
ax.set_autoscaley_on(False)
ax.set_ylim([32, 43])

# 取消x軸的自動縮放,并定義上下限
ax.set_autoscalex_on(False)
ax.set_xlim([-126, -112])

# plt.scatter()參數說明
# validation_examples["longitude"],validation_examples["latitude"]:代表x,y
# cmap:Colormap,顏色表
# c:color(色彩,或者顏色序列)
plt.scatter(validation_examples["longitude"],
            validation_examples["latitude"],
            cmap="coolwarm",
            c=validation_targets["median_house_value"] / validation_targets["median_house_value"].max())

ax = plt.subplot(1,2,2)
ax.set_title("Training Data")

ax.set_autoscaley_on(False)
ax.set_ylim([32, 43])
ax.set_autoscalex_on(False)
ax.set_xlim([-126, -112])
plt.scatter(training_examples["longitude"],
            training_examples["latitude"],
            cmap="coolwarm",
            c=training_targets["median_house_value"] / training_targets["median_house_value"].max())
_ = plt.plot()

當當當當,這個圖的問題很明顯呢,訓練和測試的數據差異很大呢,問題在哪里呢? 都是一個數據集的哎,其實就是處理數據的時候,忘記了隨機排序了(再次說明打亂順序真的很重要,我們永遠無法預知原本序列的數據可能出現哪些問題),此外采用圖標分析也很重要,能夠在訓練之前幫助我們發現問題,不然后面就完蛋啦,怎么訓練都不會有好的結果的。

調整后的結果

現在很像一個地圖了

訓練和評估模型

我們會使用數據集中的所有特征訓練一個線性回歸器,定義一下以前將數據加載到 TensorFlow 模型中時所使用的同一輸入函數

def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):  
    features = {key:np.array(value) for key,value in dict(features).items()}   
                                        
    ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit
    ds = ds.batch(batch_size).repeat(num_epochs)

    if shuffle:
      ds = ds.shuffle(10000)
    
    features, labels = ds.make_one_shot_iterator().get_next()
    return features, labels

由于我們現在使用的是多個輸入特征,因此需要把用于將特征列配置為獨立函數的代碼模塊化。(目前此代碼相當簡單,因為我們的所有特征都是數值,但當我們在今后的練習中使用其他類型的特征時,會基于此代碼進行構建。)

def construct_feature_columns(input_features):
  return set([tf.feature_column.numeric_column(my_feature)
              for my_feature in input_features])

接下來,繼續完成下面的 train_model() 代碼,以設置輸入函數和計算預測。
但要確保針對相應數據集調用 predict()比較訓練數據和驗證數據的損失

def train_model(
    learning_rate,
    steps,
    batch_size,
    training_examples,
    training_targets,
    validation_examples,
    validation_targets):

  periods = 10
  steps_per_period = steps / periods
  
  # 創建線性回歸模型并設定好特征列和優化器
  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
  linear_regressor = tf.estimator.LinearRegressor(
      feature_columns=construct_feature_columns(training_examples),
      optimizer=my_optimizer
  )
  
  # 創建訓練、預測(使用訓練集的數據)、驗證(使用驗證集的數據)的輸入函數
  training_input_fn = lambda: my_input_fn(
      training_examples, 
      training_targets["median_house_value"], 
      batch_size=batch_size)
  predict_training_input_fn = lambda: my_input_fn(
      training_examples, 
      training_targets["median_house_value"], 
      num_epochs=1, 
      shuffle=False)
  predict_validation_input_fn = lambda: my_input_fn(
      validation_examples, validation_targets["median_house_value"], 
      num_epochs=1, 
      shuffle=False)

  # 訓練(周期性輸出結果)
  print "Training model..."
  print "RMSE (on training data):"
  training_rmse = []
  validation_rmse = []
  for period in range (0, periods):
    # 按照訓練steps進行周期性訓練
    linear_regressor.train(
        input_fn=training_input_fn,
        steps=steps_per_period,
    )
    # 記錄預測值(分別使用訓練集和驗證集)
    training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)
    training_predictions = np.array([item["predictions"][0] for item in training_predictions])
    
    validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)
    validation_predictions = np.array([item["predictions"][0] for item in validation_predictions])
    
    
    # 計算RMSE(使用訓練值和驗證值)
    training_root_mean_squared_error = math.sqrt(
        metrics.mean_squared_error(training_predictions, training_targets))
    validation_root_mean_squared_error = math.sqrt(
        metrics.mean_squared_error(validation_predictions, validation_targets))

    print "  period %02d : %0.2f" % (period, training_root_mean_squared_error)

    training_rmse.append(training_root_mean_squared_error)
    validation_rmse.append(validation_root_mean_squared_error)
  print "Model training finished."

  plt.ylabel("RMSE")
  plt.xlabel("Periods")
  plt.title("Root Mean Squared Error vs. Periods")
  plt.tight_layout()
  plt.plot(training_rmse, label="training")
  plt.plot(validation_rmse, label="validation")
  # plt.legend()畫圖例,圖中右上角
  plt.legend()

  return linear_regressor

訓練...

linear_regressor = train_model(
    learning_rate=0.00003,
    steps=500,
    batch_size=5,
    training_examples=training_examples,
    training_targets=training_targets,
    validation_examples=validation_examples,
    validation_targets=validation_targets)

因為使用的features較多,要耐心等一會兒就可以看到使用訓練值和校驗值的區別了,以及多特征的效果怎么樣

Training model...
RMSE (on training data):
period 00 : 217.67
period 01 : 201.13
period 02 : 186.67
period 03 : 176.46
period 04 : 170.31
period 05 : 167.41
period 06 : 166.75
period 07 : 166.49
period 08 : 167.72
period 09 : 169.76
Model training finished.
learning_rate=0.00003

要注意這是兩條線哦,還有一條是校驗集的結果,真的是很貼合了哎,說明模型效果挺好的

上面的learning_rate=0.00003,最終的rmse為169.76,這比上次的合成特征的高了好多,所以下面嘗試修改learning_rate
learning_rate=0.00015

learning_rate=0.005

learning_rate=0.05

我們會發現這次的損失函數曲線好像很復雜的樣子。。。。emmmmmmm,其實到這里,我還沒有調好,不過不管啦,下一篇我會說明一下,多特征的時候怎么來調節超參數(其實我只是比較懶.....)

最后,再看看以學習率為0.00003訓練出來的模型,遇到測試集的效果吧

california_housing_test_data = pd.read_csv("https://storage.googleapis.com/mledu-datasets/california_housing_test.csv", sep=",")

test_examples = preprocess_features(california_housing_test_data)
test_targets = preprocess_targets(california_housing_test_data)

predict_test_input_fn = lambda: my_input_fn(
      test_examples, 
      test_targets["median_house_value"], 
      num_epochs=1, 
      shuffle=False)

test_predictions = linear_regressor.predict(input_fn=predict_test_input_fn)
test_predictions = np.array([item["predictions"][0] for item in test_predictions])

root_mean_squared_error = math.sqrt(
    metrics.mean_squared_error(test_predictions, test_targets))

print "Final RMSE (on test data): %0.2f" % root_mean_squared_error

Final RMSE (on test data): 162.84
結果很接近了呢,說明沒有過擬合。

講完。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/44655.html

相關文章

  • 正則化&&邏輯回歸

    摘要:以用于檢測垃圾郵件的邏輯回歸模型為例。邏輯回歸的損失函數線性回歸的損失函數是平方損失。正則化在邏輯回歸建模中極其重要。 正則化:簡單性 查看以下泛化曲線,該曲線顯示的是訓練集和驗證集相對于訓練迭代次數的損失。 showImg(https://segmentfault.com/img/bVbahiL?w=750&h=322);上圖顯示的是某個模型的訓練損失逐漸減少,但驗證損失最終增加。換...

    xushaojieaaa 評論0 收藏0
  • 機器學習 面試常見問題&答案 ②

    摘要:出現方差是正常的,但方差過高表明模型無法將其預測結果泛化到從中抽取訓練樣本的較大母體。機器學習中的學習曲線是一種可視化圖形,能根據一系列訓練實例中的訓練和測試數據比較模型的指標性能。 欠擬合(通常代表高偏差) 精度 如前所述如果模型具有足夠的數據,但因不夠復雜而無法捕捉基本關系,則會出現偏差。這樣一來,模型一直會系統地錯誤表示數據,從而導致預測精度低。這種現象叫做欠擬合(und...

    gself 評論0 收藏0

發表評論

0條評論

SimpleTriangle

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<