分類
發燒車訊

Tensorflow2 自定義數據集圖片完成圖片分類任務

對於自定義數據集的圖片任務,通用流程一般分為以下幾個步驟:

  • Load data

  • Train-Val-Test

  • Build model

  • Transfer Learning

其中大部分精力會花在數據的準備和預處理上,本文用一種較為通用的數據處理手段,並通過手動構建,簡單模型, 層數較深的resnet網絡,和基於VGG19的遷移學習。

你可以通過這個例子,快速搭建網絡,並訓練處一個較為滿意的結果。

1. Load data

數據集來自Pokemon的5分類數據, 每一種的圖片數量為200多張,是一個較小型的數據集。

官方項目鏈接:

Keras and Convolutional Neural Networks (CNNs)

1.1 數據集介紹

Pokemon文件夾中包含5個子文件,其中每個子文件夾名為對應的類別名。文件夾中包含有png, jpeg的圖片文件。

1.2 解題思路

  • 由於文件夾中沒有劃分,訓練集和測試集,所以需要構建一個csv文件讀取所有的文件,及其類別

  • shuffle數據集以後,劃分Train_val_test

  • 對數據進行預處理, 數據標準化,數據增強, 可視化處理

“””python
# 創建数字編碼錶

  import os
  import glob
  import random
  import csv
  import tensorflow as tf
  from tensorflow import keras
  import matplotlib.pyplot as plt
  import time
  
  
  def load_csv(root, filename, name2label):
      """
      將分散在各文件夾中的圖片, 轉換為圖片和label對應的一個dataset文件, 格式為csv
      :param root: 文件路徑(每個子文件夾中的文件屬於一類)
      :param filename: 文件名
      :param name2label: 類名編碼錶  {'類名1':0, '類名2':1..}
      :return: images, labels
      """
      # 判斷是否csv文件已經生成
      if not os.path.exists(os.path.join(root, filename)):  # join-將路徑與文件名何為一個路徑並返回(沒有會生成新路徑)
          images = []  # 存的是文件路徑
          for name in name2label.keys():
              # pokemon\pikachu\00000001.png
              # glob.glob() 利用通配符檢索路徑內的文件,類似於正則表達式
              images += glob.glob(os.path.join(root, name, '*'))  # png, jpg, jpeg
          print(name2label)
          print(len(images), images)
  
          random.shuffle(images)
  
          with open(os.path.join(root, filename), 'w', newline='') as f:
              writer = csv.writer(f)
              for img in images:
                  name = img.split(os.sep)[1]  # os.sep 表示分隔符 window-'\\' , linux-'/'
                  label = name2label[name]  # 0, 1, 2..
                  # 'pokemon\\bulbasaur\\00000000.png', 0
                  writer.writerow([img, label])  # 如果不設定newline='', 2個數據會分為2行寫
              print('write into csv file:', filename)
  
      # 讀取現有文件
      images, labels = [], []
      with open(os.path.join(root, filename)) as f:
          reader = csv.reader(f)
          for row in reader:
              # 'pokemon\\bulbasaur\\00000000.png', 0
              img, label = row
              label = int(label)  # str-> int
              images.append(img)
              labels.append(label)
  
      assert len(images) == len(labels)
  
      return images, labels
  
  
  def load_pokemon(root, mode='train'):
      """
      # 創建数字編碼錶
      :param root: root path
      :param mode: train, valid, test
      :return: images, labels, name2label
      """
  
      name2label = {}  # {'bulbasaur': 0, 'charmander': 1, 'mewtwo': 2, 'pikachu': 3, 'squirtle': 4}
      for name in sorted(os.listdir(os.path.join(root))):
          # sorted() 是為了復現結果的一致性
          # os.listdir - 返迴路徑下的所有文件(文件夾,文件)列表
          if not os.path.isdir(os.path.join(root, name)):  # 是否為文件夾且是否存在
              continue
          # 每個類別編碼一個数字
          name2label[name] = len(name2label)
  
      # 讀取label
      images, labels = load_csv(root, 'images.csv', name2label)
  
      # 劃分數據集 [6:2:2]
      if mode == 'train':
          images = images[:int(0.6 * len(images))]
          labels = labels[:int(0.6 * len(labels))]  # len(images) == len(labels)
  
      elif mode == 'valid':
          images = images[int(0.6 * len(images)):int(0.8 * len(images))]
          labels = labels[int(0.6 * len(labels)):int(0.8 * len(labels))]
  
      else:
          images = images[int(0.8 * len(images)):]
          labels = labels[int(0.8 * len(labels)):]
  
      return images, labels, name2label
  
  
  # imagenet 數據集均值, 方差
  img_mean = tf.constant([0.485, 0.456, 0.406])  # 3 channel
  img_std = tf.constant([0.229, 0.224, 0.225])
  
  def normalization(x, mean=img_mean, std=img_std):
      # [224, 224, 3]
      x = (x - mean) / std
      return x
  
  def denormalization(x, mean=img_mean, std=img_std):
      x = x * std + mean
      return x
  
  
  def preprocess(x, y):
      # x: path, y: label
      x = tf.io.read_file(x)  # 2進制
      # x = tf.image.decode_image(x)
      x = tf.image.decode_jpeg(x, channels=3)  # RGBA
      x = tf.image.resize(x, [244, 244])
  
      # data augmentation
      # x = tf.image.random_flip_up_down(x)
      x = tf.image.random_flip_left_right(x)
      x = tf.image.random_crop(x, [224, 224, 3])  # 模型縮減比例不宜過大,否則會增大訓練難度
  
      x = tf.cast(x, dtype=tf.float32) / 255. # unit8 -> float32
      # U[0,1] -> N(0,1)  # 提高訓練準確度
      x = normalization(x)
  
      y = tf.convert_to_tensor(y)
  
      return x, y
  
  def main():
      images, labels, name2label = load_pokemon('pokemon', 'train')
      print('images:', len(images), images)
      print('labels:', len(labels), labels)
      # print(name2label)
  
      # .map()函數要位於.batch()之前, 否則 x=tf.io.read_file()會一次讀取一個batch的圖片,從而報錯
      db = tf.data.Dataset.from_tensor_slices((images, labels)).map(preprocess).shuffle(1000).batch(32)
  
      # tf.summary()
      # 提供了各類方法(支持各種多種格式)用於保存訓練過程中產生的數據(比如loss_value、accuracy、整個variable),
      # 這些數據以日誌文件的形式保存到指定的文件夾中。
  
      # 數據可視化:而tensorboard可以將tf.summary()
      # 記錄下來的日誌可視化,根據記錄的數據格式,生成折線圖、統計直方圖、圖片列表等多種圖。
      # tf.summary()
      # 通過遞增的方式更新日誌,這讓我們可以邊訓練邊使用tensorboard讀取日誌進行可視化,從而實時監控訓練過程。
      writer = tf.summary.create_file_writer('logs')
      for step, (x, y) in enumerate(db):
          with writer.as_default():
              x = denormalization(x)
              tf.summary.image('img', x, step=step, max_outputs=9)  # STEP:默認選項,指的是橫軸显示的是訓練迭代次數
  
              time.sleep(5)
  
  
  
  if __name__ == '__main__':
      main()

“””

2. 構建模型進行訓練

2.1 自定義小型網絡

由於數據集數量較少,大型網絡的訓練中往往會出現過擬合情況,這裏就定義了一個2層卷積的小型網絡。
引入early_stopping回調函數后,3個epoch沒有較大變化的情況下,模型訓練的準確率為0.8547

“””
# 1. 自定義小型網絡
model = keras.Sequential([
layers.Conv2D(16, 5, 3),
layers.MaxPool2D(3, 3),
layers.ReLU(),
layers.Conv2D(64, 5, 3),
layers.MaxPool2D(2, 2),
layers.ReLU(),
layers.Flatten(),
layers.Dense(64),
layers.ReLU(),
layers.Dense(5)
])

  model.build(input_shape=(None, 224, 224, 3))  
  model.summary()
  
  early_stopping = EarlyStopping(
      monitor='val_loss',
      patience=3,
      min_delta=0.001
  )
  
  
  model.compile(optimizer=optimizers.Adam(lr=1e-3),
                 loss=losses.CategoricalCrossentropy(from_logits=True),
                 metrics=['accuracy'])
  model.fit(db_train, validation_data=db_val, validation_freq=1, epochs=100,
             callbacks=[early_stopping])
  model.evaluate(db_test)

“””

2.2 自定義的Resnet網絡

resnet 網絡對於層次較深的網絡的可訓練型提升很大,主要是通過一個identity layer保證了深層次網絡的訓練效果不會弱於淺層網絡。
其他文章中有詳細介紹resnet的搭建,這裏就不做贅述, 這裏構建了一個resnet18網絡, 準確率0.7607。

“””
import os

  import numpy as np
  import tensorflow as tf
  from tensorflow import keras
  from tensorflow.keras import layers
  
  tf.random.set_seed(22)
  np.random.seed(22)
  os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  assert tf.__version__.startswith('2.')
  
  
  class ResnetBlock(keras.Model):
  
      def __init__(self, channels, strides=1):
          super(ResnetBlock, self).__init__()
  
          self.channels = channels
          self.strides = strides
  
          self.conv1 = layers.Conv2D(channels, 3, strides=strides,
                                     padding=[[0, 0], [1, 1], [1, 1], [0, 0]])
          self.bn1 = keras.layers.BatchNormalization()
          self.conv2 = layers.Conv2D(channels, 3, strides=1,
                                     padding=[[0, 0], [1, 1], [1, 1], [0, 0]])
          self.bn2 = keras.layers.BatchNormalization()
  
          if strides != 1:
              self.down_conv = layers.Conv2D(channels, 1, strides=strides, padding='valid')
              self.down_bn = tf.keras.layers.BatchNormalization()
  
      def call(self, inputs, training=None):
          residual = inputs
  
          x = self.conv1(inputs)
          x = tf.nn.relu(x)
          x = self.bn1(x, training=training)
          x = self.conv2(x)
          x = tf.nn.relu(x)
          x = self.bn2(x, training=training)
  
          # 殘差連接
          if self.strides != 1:
              residual = self.down_conv(inputs)
              residual = tf.nn.relu(residual)
              residual = self.down_bn(residual, training=training)
  
          x = x + residual
          x = tf.nn.relu(x)
          return x
  
  
  class ResNet(keras.Model):
  
      def __init__(self, num_classes, initial_filters=16, **kwargs):
          super(ResNet, self).__init__(**kwargs)
  
          self.stem = layers.Conv2D(initial_filters, 3, strides=3, padding='valid')
  
          self.blocks = keras.models.Sequential([
              ResnetBlock(initial_filters * 2, strides=3),
              ResnetBlock(initial_filters * 2, strides=1),
              # layers.Dropout(rate=0.5),
  
              ResnetBlock(initial_filters * 4, strides=3),
              ResnetBlock(initial_filters * 4, strides=1),
  
              ResnetBlock(initial_filters * 8, strides=2),
              ResnetBlock(initial_filters * 8, strides=1),
  
              ResnetBlock(initial_filters * 16, strides=2),
              ResnetBlock(initial_filters * 16, strides=1),
          ])
  
          self.final_bn = layers.BatchNormalization()
          self.avg_pool = layers.GlobalMaxPool2D()
          self.fc = layers.Dense(num_classes)
  
      def call(self, inputs, training=None):
          # print('x:',inputs.shape)
          out = self.stem(inputs, training = training)
          out = tf.nn.relu(out)
  
          # print('stem:',out.shape)
  
          out = self.blocks(out, training=training)
          # print('res:',out.shape)
  
          out = self.final_bn(out, training=training)
          # out = tf.nn.relu(out)
  
          out = self.avg_pool(out)
  
          # print('avg_pool:',out.shape)
          out = self.fc(out)
  
          # print('out:',out.shape)
  
          return out
  
  
  def main():
      num_classes = 5
  
      resnet18 = ResNet(5)
      resnet18.build(input_shape=(None, 224, 224, 3))
      resnet18.summary()
  
  
  if __name__ == '__main__':
      main()

“””

“””
# 2.resnet18訓練, 圖片數量較小,訓練結果不是特別好
# resnet = ResNet(5) # 0.7607
# resnet.build(input_shape=(None, 224, 224, 3))
# resnet.summary()
“””

2.3 VGG19遷移學習

遷移學習利用了數據集之間的相似性,對於數據集數量較少的時候,訓練效果會遠優於其他。
在訓練過程中,使用include_top=False, 去掉最後分類的基層Dense, 重新構建並訓練就可以了。準確率0.9316

“””
# 3. VGG19遷移學習,遷移學習利用數據集之間的相似性, 結果遠好於其他2種
# 為了方便,這裏仍然使用resnet命名
net = tf.keras.applications.VGG19(weights=’imagenet’, include_top=False, pooling=’max’ )
net.trainable = False
resnet = keras.Sequential([
net,
layers.Dense(5)
])
resnet.build(input_shape=(None, 224, 224, 3)) # 0.9316
resnet.summary()

  early_stopping = EarlyStopping(
      monitor='val_loss',
      patience=3,
      min_delta=0.001
  )
  
  
  resnet.compile(optimizer=optimizers.Adam(lr=1e-3),
                 loss=losses.CategoricalCrossentropy(from_logits=True),
                 metrics=['accuracy'])
  resnet.fit(db_train, validation_data=db_val, validation_freq=1, epochs=100,
             callbacks=[early_stopping])
  resnet.evaluate(db_test)

“””

附錄:

train_scratch.py 代碼

“””

import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers, optimizers, losses
from tensorflow.keras.callbacks import EarlyStopping

tf.random.set_seed(22)
np.random.seed(22)
assert tf.__version__.startswith('2.')

# 設置GPU顯存按需分配
# gpus = tf.config.experimental.list_physical_devices('GPU')
# if gpus:
#     try:
#         # Currently, memory growth needs to be the same across GPUs
#         for gpu in gpus:
#             tf.config.experimental.set_memory_growth(gpu, True)
#         logical_gpus = tf.config.experimental.list_logical_devices('GPU')
#         print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
#     except RuntimeError as e:
#         # Memory growth must be set before GPUs have been initialized
#         print(e)

from pokemon import load_pokemon, normalization
from resnet import ResNet


def preprocess(x, y):
    # x: 圖片的路徑,y:圖片的数字編碼
    x = tf.io.read_file(x)
    x = tf.image.decode_jpeg(x, channels=3)  # RGBA
    # 圖片縮放
    # x = tf.image.resize(x, [244, 244])
    # 圖片旋轉
    # x = tf.image.rot90(x,2)
    # 隨機水平翻轉
    x = tf.image.random_flip_left_right(x)
    # 隨機豎直翻轉
    # x = tf.image.random_flip_up_down(x)

    # 圖片先縮放到稍大尺寸
    x = tf.image.resize(x, [244, 244])
    # 再隨機裁剪到合適尺寸
    x = tf.image.random_crop(x, [224, 224, 3])

    # x: [0,255]=> -1~1
    x = tf.cast(x, dtype=tf.float32) / 255.
    x = normalization(x)
    y = tf.convert_to_tensor(y)
    y = tf.one_hot(y, depth=5)

    return x, y


batchsz = 32

# create train db
images1, labels1, table = load_pokemon('pokemon', 'train')
db_train = tf.data.Dataset.from_tensor_slices((images1, labels1))
db_train = db_train.shuffle(1000).map(preprocess).batch(batchsz)
# create validation db
images2, labels2, table = load_pokemon('pokemon', 'valid')
db_val = tf.data.Dataset.from_tensor_slices((images2, labels2))
db_val = db_val.map(preprocess).batch(batchsz)
# create test db
images3, labels3, table = load_pokemon('pokemon', mode='test')
db_test = tf.data.Dataset.from_tensor_slices((images3, labels3))
db_test = db_test.map(preprocess).batch(batchsz)


# 1. 自定義小型網絡
# resnet = keras.Sequential([
#     layers.Conv2D(16, 5, 3),
#     layers.MaxPool2D(3, 3),
#     layers.ReLU(),
#     layers.Conv2D(64, 5, 3),
#     layers.MaxPool2D(2, 2),
#     layers.ReLU(),
#     layers.Flatten(),
#     layers.Dense(64),
#     layers.ReLU(),
#     layers.Dense(5)
# ])  # 0.8547


# 2.resnet18訓練, 圖片數量較小,訓練結果不是特別好
# resnet = ResNet(5)  # 0.7607
# resnet.build(input_shape=(None, 224, 224, 3))
# resnet.summary()


# 3. VGG19遷移學習,遷移學習利用數據集之間的相似性, 結果遠好於其他2種
net = tf.keras.applications.VGG19(weights='imagenet', include_top=False, pooling='max' )
net.trainable = False
resnet = keras.Sequential([
    net,
    layers.Dense(5)
])
resnet.build(input_shape=(None, 224, 224, 3))   # 0.9316
resnet.summary()

early_stopping = EarlyStopping(
    monitor='val_loss',
    patience=3,
    min_delta=0.001
)


resnet.compile(optimizer=optimizers.Adam(lr=1e-3),
               loss=losses.CategoricalCrossentropy(from_logits=True),
               metrics=['accuracy'])
resnet.fit(db_train, validation_data=db_val, validation_freq=1, epochs=100,
           callbacks=[early_stopping])
resnet.evaluate(db_test)

“””

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

為什麼用抓包工具看HTTPS包是明文的

測試或者開發調試的過程中,經常會進行抓包分析,並且裝上抓包工具的證書就能抓取 HTTPS 的數據包並显示。由此就產生了一個疑問,為什麼抓包工具裝上證書後就能抓到 HTTPS 的包並显示呢?不是說 HTTPS 是加密傳輸的嗎?

今天這篇文章就來探究下上面這個問題,要解釋清楚這個問題,我會通過解答以下兩個問題來講述:

  1. HTTPS 到底是什麼?
  2. 抓包工具抓包的原理?

HTTPS 到底是什麼

HTTP 作為一種被廣泛使用的傳輸協議,也存在一些的缺點:

  1. 無狀態(可以通過 Cookie 或 Session 解決);
  2. 明文傳輸;
  3. 不安全;

為了解決 “明文” 和 “不安全” 兩個問題,就產生了 HTTPSHTTPS 不是一種單獨的協議,它是由 HTTP + SSL/TLS 組成。

HTTP與HTTPS

所以要理解 HTTPS 就只需在 HTTP 的基礎上理解 SSL/TLS (TLS 是 SSL 的後續版本,現在一般使用 TLS),下面就來了解下 TLS 是什麼。

TLS

傳輸層安全性協議(英語:Transport Layer Security,縮寫:TLS)及其前身安全套接層(英語:Secure Sockets Layer,縮寫:SSL)是一種安全協議,目的是為互聯網通信提供安全及數據完整性保障。

TLS 由記錄協議、握手協議、警報協議、變更密碼規範協議、擴展協議等幾個子協議組成,綜合使用了對稱加密、非對稱加密、身份認證等許多密碼學前沿技術。

  • 記錄協議 規定
    TLS 收發數據的基本單位為:記錄。類似
    TCP 里的
    segment,所有其它子協議都需要通過記錄協議發出。
  • 警報協議 的職責是向對方發出警報信息,類似於
    HTTP 里的狀態碼。
  • 握手協議
    TLS 里最複雜的子協議,瀏覽器和服務器在握手過程中會協商
    TLS 版本號、隨機數、密碼套件等信息,然後交換證書和密鑰參數,最終雙方協商得到會話密鑰,用於後續的混合加密系統。
  • 變更密碼規範協議 用於告知對方,後續的數據都將使用加密傳輸。

TLS 的握手過程:

TLS握手過程

握手過程抓包显示:

TLS抓包
TLS所傳輸的數據

交換密鑰的過程為:

  1. 客戶端發起一個請求給服務器;
  2. 服務器生成一對非對稱的公鑰(
    pubkey)和私鑰(
    privatekey),然後把公鑰附加到一個
    CA数字證書 上返回給客戶端;
  3. 客戶端校驗該證書是否合法(通過瀏覽器內置的廠商根證書等手段校驗),然後從證書中提取出公鑰(
    pubkey);
  4. 客戶端生成一個隨機數(
    key),然後使用公鑰(
    pubkey)對這個隨機數進行加密后發送給服務器;
  5. 服務器利用私鑰(
    privatekey)對收到的隨機數密文進行解密得到
    key ;
  6. 後續客戶端和服務器傳輸數據使用該
    key 進行加密后再傳輸;

抓包工具抓包的原理

先來看看抓 HTTP 包的原理

HTTP抓包過程

  1. 首先抓包工具會提供出代理服務,客戶端需要連接該代理;
  2. 客戶端發出
    HTTP 請求時,會經過抓包工具的代理,抓包工具將請求的原文進行展示;
  3. 抓包工具使用該原文將請求發送給服務器;
  4. 服務器返回結果給抓包工具,抓包工具將返回結果進行展示;
  5. 抓包工具將服務器返回的結果原樣返回給客戶端;

抓包工具就相當於個透明的中間人,數據經過的時候它一隻手接到數據,然後另一隻手把數據傳出去。

再來看看 HTTPS 的抓包

HTTPS抓包過程

這個時候抓包工具對客戶端來說相當於服務器,對服務器來說相當於客戶端。在這個傳輸過程中,客戶端會以為它就是目標服務器,服務器也會以為它就是請求發起的客戶端。

  1. 客戶端連接抓包工具提供的代理服務;
  2. 客戶端需要安裝抓包工具的根證書;
  3. 客戶端發出
    HTTPS 請求,抓包工具模擬服務器與客戶端進行
    TLS 握手交換密鑰等流程;
  4. 抓包工具發送一個
    HTTPS 請求給客戶端請求的目標服務器,並與目標服務器進行
    TLS 握手交換密鑰等流程;
  5. 客戶端使用與抓包工具協定好的密鑰加密數據后發送給抓包工具;
  6. 抓包工具使用與客戶端協定好的密鑰解密數據,並將結果進行展示;
  7. 抓包工具將解密后的客戶端數據,使用與服務器協定好的密鑰進行加密后發送給目標服務器;
  8. 服務器解密數據后,做對應的邏輯處理,然後將返回結果使用與抓包工具協定好的密鑰進行加密發送給抓包工具;
  9. 抓包工具將服務器返回的結果,用與服務器協定好的密鑰解密,並將結果進行展示;
  10. 抓包工具將解密后的服務器返回數據,使用與客戶端協定好的密鑰進行加密后發送給客戶端;
  11. 客戶端解密數據;

總結

  • HTTPS 不是單獨的一個協議,它是
    HTTP +
    SSL/TLS 的組合;
  • TLS 是傳輸層安全性協議,它會對傳輸的
    HTTP 數據進行加密,使用非對稱加密和對稱加密的混合方式;
  • 抓包工具的原理就是“偽裝“,對客戶端偽裝成服務器,對服務器偽裝成客戶端;
  • 使用抓包工具抓
    HTTPS 包必須要將抓包工具的證書安裝到客戶端本地,並設置信任;
  • HTTPS 數據只是在傳輸時進行了加密,而抓包工具是接收到數據后再重新加密轉發,所以抓包工具抓到的
    HTTPS 包可以直接看到明文;

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

三文搞懂學會Docker容器技術(上)

1,Docker簡介

  1.1 Docker是什麼?

Docker官網: https://www.docker.com/

Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從Apache2.0協議開源。
Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後發布到任何流行的 Linux 機器上,也可以實現虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
Docker 從 17.03 版本之後分為 CE(Community Edition: 社區版) 和 EE(Enterprise Edition: 企業版),我們用社區版就可以了。

  1.2 Docker架構原理?

 

Docker三要素,鏡像,容器,倉庫

1.鏡像

Docker 鏡像(Image)就是一個只讀的模板,它可以是一個可運行軟件(tomcat,mysql),也可以是一個系統(centos)。鏡像可以用來創建 Docker 容器,一個鏡像可以創建很多容器。

2.容器

Docker 利用容器(Container)獨立運行的一個或一組應用。容器是用鏡像創建的運行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。可以把容器看做是一個簡易版的 Linux 環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。容器的定義和鏡像幾乎一模一樣,也是一堆層的統一視角,唯一區別在於容器的最上面那一層是可讀可寫的。

3.倉庫

倉庫(Repository)是集中存放鏡像文件的場所,類似GitHub存放項目代碼一樣,只不過Docker Hub是由來存鏡像(image)的。倉庫(Repository)和倉庫註冊服務器(Registry)是有區別的。倉庫註冊服務器上往往存放着多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的標籤(tag,類似版本號)。

倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。

最大的公開倉庫是 Docker Hub(https://hub.docker.com/),存放了數量龐大的鏡像供用戶下載。國內的公開倉庫包括阿里雲 、網易雲 等。

 

容器與鏡像的關係類似於面向對象編程中的對象與類。

Docker 面向對象
容器 對象
鏡像

  1.3 Docker有什麼用?

    1,簡化環境搭建,提高開發生命周期效率;

    2,大大簡化運維工作量;

    3,微服務利器;

  1.4 Docker容器與虛擬機區別?

Docker是一種輕量級的虛擬化技術,比傳統的虛擬機性能更好。

下圖是虛擬機的體繫結構:

 

  • server – 表示真實電腦。
  • Host OS – 真實電腦的操作系統,例如:Windows,Linux
  • Hypervisor – 虛擬機平台,模擬硬件,如VMWare,VirtualBox
  • Guest OS – 虛擬機平台上安裝的操作系統,例如CentOS Linux
  • App – 虛擬機操作系統上的應用,例如nginx

 

下圖是Docker的體繫結構:

  • server – 表示真實電腦。
  • Host OS – 真實電腦的操作系統,例如:Windows,Linux
  • Docker Engine – 新一代虛擬化技術,不需要包含單獨的操作系統。
  • App – 所有的應用程序現在都作為Docker容器運行。

 

這種體繫結構的明顯優勢是,不需要為虛擬機操作系統提供硬件模擬。所有應用程序都作為Docker容器工作,性能更好。

  Docker容器 虛擬機(VM)
操作系統 與宿主機共享OS 宿主機OS上運行宿主機OS
存儲大小 鏡像小,便於存儲與傳輸 鏡像龐大(vmdk等)
運行性能 幾乎無額外性能損失 操作系統額外的cpu、內存消耗
移植性 輕便、靈活、適用於Linux 笨重、與虛擬化技術耦合度高
硬件親和性  面向軟件開發者 面向硬件運維者

 

Docker優點:輕量級,速度快,運行應用隔離,方便維護…

2,Docker安裝

  2.1 Docker版本介紹

Docker從1.13版本之後採用時間線的方式作為版本號,分為社區版CE和企業版EE。

社區版是免費提供給個人開發者和小型團體使用的,企業版會提供額外的收費服務,比如經過官方測試認證過的基礎設施、容器、插件等。

社區版按照stable和edge兩種方式發布,每個季度更新stable版本,如17.06,17.09;每個月份更新edge版本,如17.09,17.10。

我們平時用社區版就足夠了。所以我們安裝社區版;

  2.2 Docker安裝官方文檔

我們主要參考:https://docs.docker.com/install/linux/docker-ce/centos/  來安裝;

  2.3 工具準備

前置課程:Centos課程  http://www.java1234.com/javaxuexiluxiantu.html

打包下載: http://pan.baidu.com/s/1i55jJAt

虛擬機 VMware

centos7安裝下虛擬機VM上;

連接工具 才用 FinalShell  官方地址:http://www.hostbuf.com/

  2.4 Docker安裝步驟

我們切換到root用戶

1、Docker 要求 CentOS 系統的內核版本高於 3.10 ,查看本頁面的前提條件來驗證你的CentOS 版本是否支持 Docker 。

通過 uname -r 命令查看你當前的內核版本

 $ uname -r

2、使用 root 權限登錄 Centos。確保 yum 包更新到最新。

$ yum update

3、卸載舊版本(如果安裝過舊版本的話)

$ yum remove docker  docker-common docker-selinux docker-engine

4、安裝需要的軟件包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的

$ yum install -y yum-utils device-mapper-persistent-data lvm2

5、設置yum源

$ yum-config-manager –add-repo https://download.docker.com/linux/centos/docker-ce.repo

6,安裝最新版本的Docker

$ yum install docker-ce docker-ce-cli containerd.io

7,啟動Docker並設置開機啟動

$ systemctl start docker

$ systemctl enable docker

8,驗證Docker

$ docker version

 

說明安裝OK;

9,Docker HelloWorld測試;

$ docker run hello-world

 

因為本地沒有這個鏡像,所以從遠程官方倉庫去拉取,下載;

然後我們再執行一次;

 

OK了

  2.5 Docker配置阿里雲鏡像倉庫

Docker默認遠程倉庫是 https://hub.docker.com/

比如我們下載一個大點的東西,龜速

 

由於是國外主機,類似Maven倉庫,慢得一腿,經常延遲,破損;

所以我們一般都是配置國內鏡像,比如阿里雲,網易雲等;推薦阿里雲,穩定點;

配置步驟如下:

1,登錄進入阿里雲鏡像服務中心,獲取鏡像地址

進入阿里雲容器鏡像服務地址:點這裏快速進入

使用你的淘寶賬號密碼登錄

 

這裏我們獲取鏡像地址;

2,在/etc/docker目錄下找到在daemon.json文件(沒有就新建),將下面內容寫入

{

 “registry-mirrors”: [“https://xxxxxxx.mirror.aliyuncs.com”]

}

3,重啟daemon

systemctl daemon-reload

4,重啟docker服務

systemctl restart docker

5,測試

由於速度太快,截圖都難;

 

3,HelloWorld運行原理

運行  docker run hello-world

本地倉庫未能找到該鏡像,然後去遠程倉庫尋找以及下載該鏡像;

然後我們再執行該命令:

出來了 Hellowold。我們具體來分析下 執行原理和過程;

從左到右 client客戶端,Docker運行主機,遠程倉庫;

docker build ,pull,run分別是 構建,拉取,運行命令,後面再細講;

中間Docker主機里有 Docker daemon主運行線程,以及Containers容器,容器里可以運行很多實例,(實例是從右側Images鏡像實例化出來的)Images是存儲再本地的鏡像文件,比如 Redis,Tomat這些鏡像文件;

右側是Registry鏡像倉庫,默認遠程鏡像倉庫 https://hub.docker.com/  不過是國外主機,下載很慢,不穩定,所以我們後面要配置成阿里雲倉庫鏡像地址,穩定快捷;

執行 docker run hello-world的過程看如下圖例:

 

 

 

4,Docker基本命令

   4.1 啟動Docker

           systemctl start docker

  4.2 停止Docker

         systemctl stop docker

  4.3 重啟Docker

       systemctl restart docker

  4.4 開機啟動Docker

     systemctl enable docker

  4.5 查看Docker概要信息

   docker info

  4.6 查看Docker幫助文檔

   docker –help

  4.7 查看Docker版本信息

     docker version

5,Docker鏡像

  5.1 docker images 列出本機所有鏡像

 

REPOSITORY 鏡像的倉庫源
TAG 鏡像的標籤(版本)同一個倉庫有多個TAG的鏡像,多個版本;我們用REPOSITORY:TAG來定義不同的鏡像;
IMAGE ID 鏡像ID,鏡像的唯一標識
CREATE 鏡像創建時間
SIZE 鏡像大小

OPTIONS 可選參數:

-a 显示所有鏡像(包括中間層)
q 只显示鏡像ID
-qa 可以組合
–digests 显示鏡像的摘要信息
–no-trunc 显示完整的鏡像信息 

 

  5.2 docker search 搜索鏡像

和 https://hub.docker.com/ 這裏的搜索效果一樣;

OPTIONS可選參數:

–no-trunc 显示完整的鏡像描述
-s 列出收藏數不小於指定值的鏡像
–automated 只列出Docker Hub自動構建類型的鏡像

 

 

 

  5.3 docker pull 下載鏡像

docker pull 鏡像名稱:[TAG]

注意:不加TAG,默認下載最新版本latest

  5.4 docker rmi 刪除鏡像

1,刪除單個:docker rmi 鏡像名稱:[TAG]

如果不寫TAG,默認刪除最新版本latest

有鏡像生成的容器再運行時候,會報錯,刪除失敗;

我們需要加 -f 強制刪除

2,刪除多個:docker rmi -f 鏡像名稱1:[TAG] 鏡像名稱2:[TAG]

中間空格隔開

3,刪除全部:docker rmi -f $(docker images -qa)

 

 

——————————————————————————————————————————

作者: java1234_小鋒

出處:https://www.cnblogs.com/java688/p/13132444.html

版權:本站使用「CC BY 4.0」創作共享協議,轉載請在文章明顯位置註明作者及出處。

——————————————————————————————————————————

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

一文讀懂:GBDT梯度提升

先縷一縷幾個關係:

  • GBDT是gradient-boost decision tree
  • GBDT的核心就是gradient boost,我們搞清楚什麼是gradient boost就可以了
  • GBDT是boost中的一種方法,boost還有XGBoost,adaboost。

基本概念

【Boost】就是讓多個弱分類器,通過不同的集成方式,來讓多個弱分類器變成一個強分類器。

【gradient-boost】 梯度提升。簡單的說,先訓練一個弱分類器,然後弱分類器和目標值之間的殘差,作為下一個弱分類器訓練的目標值。這裡有一個非常簡單的例子

  • 第一個模型預測年齡,雖然真實值是30歲,第一個模型只給出了20歲的估計值;
  • 第二棵樹要預測的就是這個10歲的殘差,但是第二棵樹只給出了6歲的估計值;
  • 第三棵樹預測的是第二棵樹的4歲的殘差,但是………………(禁止套娃)

梯度 or 殘差 ?

對於GBDT,網上的很多文章都沒有講清楚,學習梯度還是學習殘差?從上面的那個例子來看,是學習殘差的。

其實,從來GBDT都是學習梯度的,學習殘差只是學習梯度的一個特例!

如果我們是在做一個回歸任務(就像是上面例子中預測年齡),採用平方損失:\(loss = \frac{1}{2}\sum^n_i{(y_i-\hat{y_i})^2}\)
其中\(y_i\)是真實數值,\(\hat{y_i}\)是模型預測的值。

然後想求取這個關於\(\hat{y_i}\)的梯度,那就是:
\(\frac{\partial loss}{\partial \hat{y^i}}=(-1)(y_i-\hat{y_i})\)

所以殘差在平方損失的情況下,就是等於負梯度,所以兩者一回事。

殘差過於敏感

對於數據不幹凈,沒有清晰掉異常值的數據樣本。使用平方損失對異常值過於敏感了

所以,這裡在回歸問題中,也可以考慮使用下面的兩個損失函數:

  • Absolute loss:
    \(loss=|y-\hat{y}|\)

  • Huber loss:
    這個是設置一個閾值,當\(|y-\hat{y}|\)小於這個閾值的時候,採用平方損失,當\(|y-\hat{y}|\)大於這個閾值的時候,採用類似於絕對損失的線性損失:

    這裏看一下huber loss的函數圖像:

    就是一個平方損失,一個線性損失。

然後看一下平方損失,絕對損失,huber損失對於異常值的容忍程度:

CART回歸樹分裂思路(可不看)

其實這個問題看起來問的不明所以,其實是問你決策樹如何選擇特徵的。從上面的例子可以看出來,GDBT應該是處理回歸問題的(處理連續數據的)。當然,GDBT也有辦法處理分類問題,只是這裏就不說了,這裏主要說GDBT怎麼處理回歸問題的,回歸問題能處理,那麼總有回歸離散化的辦法的

這個問題是在問:CART TREE如何選擇特徵的CART TREE就是回歸決策樹,就是之前提到的弱分類器。

一個決策樹,希望讀者已經有一個大概的理解了。簡單說就是:樣本可以根據的特徵A是否超過某一個閾值劃分成兩部分,然後劃分之後的每一個部分又可以根據某一個特徵是否超過某一個閾值再分成兩部分……

這樣我們就要做出選擇了:每一個部分是根據哪一個特徵去劃分?根據這個特徵的哪一個數值作為閾值劃分?

如果我們算力無窮,那麼自然可以遍歷每一個特徵,然後窮舉每一種可能的分割點,然後對比找到最優分割點。

那麼如何判斷分割的點的好壞呢?得給出一個cost函數,或者叫做loss函數這樣的東西吧。

\(loss= \sum_{第一部分}{(y_i-me an(y_{第一部分}))^2}+\sum_{第二部分}{(y_i-mean(y_{第二部分}))^2}\)

看一下這個公式,我把公式寫的太丑了。其實這個公式非常的好理解:現在根據某一個特徵值,根據某一個閾值把樣本分成了兩個部分:第一部分和第二部分。然後計算每一個部分的樣本的label的均值,也就是公式中的:\(mean(y_{第一部分})\),\(mean(y_{第二部分})\),然後計算第一部分中所有樣本的label與第一部分label均值之間的差的平方和,同樣的過程計算第二個部分的,兩個相加起來就是這個loss。選擇能夠讓這個loss最小的分割特徵和分割閾值,就是我們要找的東西。

其實我在學這一塊的時候,發現這個過程像是什麼?像不像聚類算法,通過上面的loss的最小化的過程,把一堆樣本分成兩類,讓兩類的類內距離最小。那個均值就像是求類中心點,計算每一個label距離類中心點的距離。(這一段看不懂也沒事

喜歡的話請關注我們的微信公眾號~【你好世界煉丹師】。

  • 公眾號主要講統計學,數據科學,機器學習,深度學習,以及一些參加Kaggle競賽的經驗。
  • 公眾號內容建議作為課後的一些相關知識的補充,飯後甜點。
  • 此外,為了不過多打擾,公眾號每周推送一次,每次4~6篇精選文章。

微信搜索公眾號:你好世界煉丹師。期待您的關注。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

熱浪席捲 澳洲全國均溫40.9度創新高

摘錄自2019年12月18日中央社報導

澳17日出現有紀錄以來最熱的一天,氣象局測到全國平均氣溫高達攝氏40.9度(華氏105.6度)。先前澳洲高溫紀錄為2013年1月時創下的攝氏40.3度。

在近日野火肆虐澳洲東岸,又有熱浪席捲各地,氣候狀況更形惡劣的情況下,高溫紀錄預料很快就會再寫新高。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

氣候暖化影響冬眠 俄羅斯小獾提早甦醒

摘錄自2020年2月13日公視報導

受到暖冬影響,冬眠的動物提早甦醒,像是在俄羅斯,動物園裡的獾原本應該睡到月底,卻在月初就爬起來玩。

在俄羅斯西伯利亞城市伊爾庫茨克的動物園,發現有兩隻獾,在二月的第一週就醒來一起玩,牠們去年這時候還在冬眠,當時還跟往年作息一樣,睡到月底。助理獸醫史達茲卡雅表示:「牠們都是小獾,也就是新生代。成年的獾都還在睡覺,牠們冬眠會比較久。」

這個月10號,當地氣溫攝氏兩度,但去年的同一天,氣溫為零下24度。此外,動物園內這隻名為藍波的刺蝟,也在上週跑出來活動,園方表示,通常這表示春天就快到了,史達茲卡雅說:「動物比我們的感覺還要強,牠們更能適應大自然的改變,牠們也會比較早感覺得到。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

福島核污染物遭沖走外洩 韓國要求日本提供資料

摘錄自2019年10月21日自由時報報導

哈吉貝颱風侵襲日本,造成許多地區出現慘重水患,放置福島核電事故輻射污染物的臨時貯存場也遭大水淹沒,部分裝有輻射污染廢棄物的袋子沖入河中,輻射廢棄物不翼而飛,韓國核電安全委員會要求日本提供該事件相關資料。

據《韓聯社》報導,韓核電安全委員會委員長嚴在植21日透露,針對福島輻射污染物垃圾袋被沖走一事,已要求日本駐韓大使館提供相關資料,日前韓奧委會也在與國際奧會(IOC)主席巴赫(Thomas Bach)會談時,向巴赫提出福島輻射污染物洩漏事件,巴赫表示會計畫確認情況。

日本環境省表示,目前在河道的輻射量並沒有變化,認為這些流出的放射性物質濃度較低,對環境不會有影響。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

颱風哈吉貝襲日滿月 農林漁損恐直逼西日本豪雨

摘錄自2019年11月12日中央社報導

颱風哈吉貝10月12日侵襲日本,到12日屆滿1個月,目前已知至少造成90人死亡、5人失蹤,目前掌握農林漁業損失已逾2200億日圓,未來可能直逼2018年西日本豪雨的逾3000億日圓。

哈吉貝10月12日從日本伊豆半島登陸侵襲東日本地區,日本經濟新聞報導,目前已知至少造成90人死亡、5人失蹤,將近300條河川流經區域發生水災,逾9萬棟民宅受災;如果從發生884起土石災害來看,這是從1982年以來,單一個颱風所造成的最慘重災情。

日本總務省消防廳表示,截至11日為止,全損或半損民宅超過1萬1000棟,淹水超過一樓地板高度的民宅超過3萬1000棟。

日本內閣府表示,截至8日為止,仍有約2800人在避難所生活,且還有不少人因為家中受災,只能暫時借住在親戚家中。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準

分類
發燒車訊

亞洲訂單能見度佳 台廠第四季有望淡季不淡

雙反最終以定價定量收場,雖然結局讓台廠短期內並未受惠中國廠商的轉單效益。但法人表示,台廠在中歐貿易戰平息後,企業策略布局已進行新一波調整,重心除轉回到中國大陸內需市場,也著重於需求大增的日本及其他亞洲市場。

其中碩禾8月正銀的出貨量已正式突破3噸,且顧客需求活絡、訂單能見度佳,出貨量有望逐月放大。加上銀價隨著美國量化寬鬆政策訊息鈍化與出現反彈,正銀收益更加穩定。另外,碩禾子公司禾迅投資的日本永和電力,在日本簽訂約50億日圓電站業務合約,將在福島建置近17MW的電站,估計明年完工後,每年可貢獻售電收入約8億日圓的收益。

昱晶日前指出雙反時因應客戶拉貨的庫存已消化完畢,目前看來客戶對第四季需求沒有出現雜音,10月接單狀況佳,11、12月份的訂單應不會出現太大問題,整體表現可望與第三季相當。

中美晶在八月營收創新高後,也宣布著重綠能題材,積極以新技術搶攻油電混合車和純電動車市場,由於油電混合車和純電動車對於晶片的需求較傳統車用量高,隨著油價攀高、環保意識抬頭,也將推升未來公司的成長力道。

新日光在宣布合併旺能後,領域囊括太陽能電池、模組到終端的系統安裝,產能亦同步抬升。而新日光轉投資的系統安裝廠永旺日前爭取到國發基金補助,以永旺今年度在國內、外的安裝目標來看,可望帶來製造端之外的穩定成長動能。

隨著太陽能產業景氣回升,國內太陽能電池廠的接單能見度開始至10月向後延伸,一線大廠產能利用率皆仍能維持在高檔,第四季有望呈現淡季不淡的局面。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

中國出臺新能源汽車補貼新政 純電動汽車直補6萬

9月17日,中國財政部、科技部、工信部、發改委聯合出臺的《關于繼續開展新能源汽車推廣應用工作的通知》(以下簡稱“通知”), 新能源家用汽車每臺直補3.5萬~6萬元(人民幣),被經濟界稱為“節能家電補貼”嫁接出了新能源汽車版。

同時,今年購買新能源汽車將最為實惠。2014年、2015年,會按照補貼標準依次下降補貼10%、20%。此次“通知”補貼的主要范疇為純電動乘用車、插電式混合動力(含增程式)乘用車、純電動專用車、燃料電池汽車四類。相比2010年4部委首次頒布的“新能源汽車補貼標準”,“通知”的最大特點是對全國普惠、優化補貼流程,並兼顧惠及生產、銷售、消費三方利益。

一步到位的購車補貼流程對消費市場是重大利好,消費者到4S店購車,即可從車款中直接減掉對應的補貼款。此後,由中央財政與車企完成結算。同時,“通知”也採取了分級補貼的形式:純電動汽車續航裏程在80~150公裏補貼3.5萬元/臺;150~250公裏補貼5萬元/臺;250公裏以上補貼6萬元/臺。插電式混合動力(含增程式)乘用車,一次直補3.5萬元。

但是,也許政策補貼可讓純電動汽車裸車購買價更低,但其綜合經濟性並不能完全超過傳統汽車。由於購車價格較高,充電不方便,以及消費者對於新能源汽車的安全係數與技術問題的擔憂,導致目前新能源汽車在中國仍沒有很大的需求。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※幫你省時又省力,新北清潔一流服務好口碑

※回頭車貨運收費標準