1. 程式人生 > >TensorFlow Keras 官方教程 * * * * *

TensorFlow Keras 官方教程 * * * * *

TensorFlow版本:1.10.0 > Guide > Keras

Keras 簡介

Keras 是建立和訓練深度學習模型的高階 API。它被用於快速原型、高階研究和生產。Keras 具有三個主要優點:

  • 好用的 API
    Keras API 簡單、穩定、容易除錯。
  • 高度模組化
    Keras API 可以像搭積木一樣來構建深度學習系統。
  • 易於擴充套件
    可以很容易地實現研究過程中的各種新奇想法。
    比如:自定義層、自定義損失函式、提升state of art 模型的效能等。

1. 匯入 tf.keras

tf.keras是 Keras API 在 TensorFlow 裡的實現。Keras 是一個高階 API,用於構建和訓練模型,同時相容 TensorFlow 的絕大部分功能,比如,

eager executiontf.data 模組,及 Estimators

tf.keras 使得 TensorFlow 更容易使用,且保持 TF 的靈活性和效能。

使用 tf.keras,首先需要在您的程式碼開始時匯入tf.keras

import tensorflow as tf
from tensorflow import keras

tf.keraskeras 絕對相容,但請注意:

  • tf.keraskeras 版本相同時,才絕對相容。可以通過 tf.keras.__version__.來檢視 tf.keras 的版本。
  • 儲存模型引數時,tf.keras 預設儲存成 checkpoint 格式。可以通過設定 save_format=‘h5’
    來儲存成 HDF5 格式。

2. 建立簡單模型

2.1 使用 Sequential API 建立簡單模型

在 Keras 裡,你用 layers 來搭建模型。一個模型(通常)是一個 layer 組成的圖(Graph)。最常見的模型型別一般是由多個 layer 堆疊體:tf.keras.Sequential 模型

以構建一個簡單的全連線網路(比如:多層感知器)為例:

model = keras.Sequential()
# Adds a densely-connected layer with 64 units to the model:
model.add(keras.layers.
Dense(64, activation='relu')) # Add another: model.add(keras.layers.Dense(64, activation='relu')) # Add a softmax layer with 10 output units: model.add(keras.layers.Dense(10, activation='softmax'))

2.2 設定層的引數

tf.keras.layers 中有很多層,下面是一些通用的建構函式的引數:

  • activation:設定層使用的啟用函式。
    指定方法:名稱 或 可呼叫物件
    預設為空。
  • kernel_initializerbias_initializer:設定層建立時,權重和偏差的初始化方法。
    指定方法:名稱 或 可呼叫物件
    預設為"Glorot uniform" initializer。
  • kernel_regularizerbias_regularizer:設定層的權重、偏差的正則化方法。比如:L1 或 L2 正則。
    預設為空。

下面是一個例項,例子中對層的引數進行了指定:

# Create a sigmoid layer:
layers.Dense(64, activation='sigmoid')
# Or:
layers.Dense(64, activation=tf.sigmoid)

# A linear layer with L1 regularization of factor 0.01 applied to the kernel matrix:
layers.Dense(64, kernel_regularizer=keras.regularizers.l1(0.01))
# A linear layer with L2 regularization of factor 0.01 applied to the bias vector:
layers.Dense(64, bias_regularizer=keras.regularizers.l2(0.01))

# A linear layer with a kernel initialized to a random orthogonal matrix:
layers.Dense(64, kernel_initializer='orthogonal')
# A linear layer with a bias vector initialized to 2.0s:
layers.Dense(64, bias_initializer=keras.initializers.constant(2.0))

3. 建立複雜模型

3.1 使用 Function API 建立複雜模型

tf.keras.Sequential 模型只適用於多層簡單堆疊網路,不能表示複雜模型。使用 Keras functional API 可以構建有複雜拓撲結構的模型。比如:

  • 多個輸入的模型(Multi-input models)
  • 多個輸出的模型(Multi-output models)
  • 有共享層的模型(Models with shared layers (the same layer called several times))
  • 有 non-sequential 資料流的模型(Models with non-sequential data flows (例如,殘差連線))

函式式 API 特點:

  1. 層是可呼叫的,返回值是一個 tensor。
  2. 輸入 tensors 和輸出 tensors 被用來定義一個 tf.keras.Model
    例項。
  3. 函式式 API 構建的模型的訓練同 Sequential 模型。

下面的程式碼使用函式式 API 構建了一個簡單的全連線網路:

inputs = keras.Input(shape=(32,))  # Returns a placeholder tensor

# A layer instance is callable on a tensor, and returns a tensor.
x = keras.layers.Dense(64, activation='relu')(inputs)
x = keras.layers.Dense(64, activation='relu')(x)
predictions = keras.layers.Dense(10, activation='softmax')(x)

# Instantiate the model given inputs and outputs.
model = keras.Model(inputs=inputs, outputs=predictions)

# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs
model.fit(data, labels, batch_size=32, epochs=5)

3.2 編寫 Model 的子類來構建模型(Model subclassing)

通過編寫 tf.keras.Model 的子類來構建一個自定義模型,並且定義你的模型的前向傳播。在 init 方法裡建立 layers。在 call 方法裡定義前向傳播過程。

當使用 eager execution 時,Model subclassing 方法特別有用(pytorch 裡確實也是這麼幹的)。

提示: 根據工作的不同,請使用不同的 API。雖然 model subclassing 提供了靈活性,但也更復雜、更容易出錯。如果可能,請儘量使用 function API。

下面是 model subclassing 例子:

class MyModel(keras.Model):

  def __init__(self, num_classes=10):
    super(MyModel, self).__init__(name='my_model')
    self.num_classes = num_classes
    # Define your layers here.
    self.dense_1 = keras.layers.Dense(32, activation='relu')
    self.dense_2 = keras.layers.Dense(num_classes, activation='sigmoid')

  def call(self, inputs):
    # Define your forward pass here,
    # using layers you previously defined (in `__init__`).
    x = self.dense_1(inputs)
    return self.dense_2(x)

  def compute_output_shape(self, input_shape):
    # You need to override this function if you want to use the subclassed model
    # as part of a functional-style model.
    # Otherwise, this method is optional.
    shape = tf.TensorShape(input_shape).as_list()
    shape[-1] = self.num_classes
    return tf.TensorShape(shape)


# Instantiates the subclassed model.
model = MyModel(num_classes=10)

# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs.
model.fit(data, labels, batch_size=32, epochs=5)

3.3 自定義 layers

可以通過編寫 tf.keras.layers.Layer 的子類來建立一個自定義 layer,該子類編寫過程中需要編寫下面的方法:

  • build:建立層的引數。Add weights with the add_weight
    method.
  • call:定義前向傳播過程。
  • compute_output_shape:指定怎麼根據輸入去計算 layer 的輸出 shape。
  • 可選地,a layer can be serialized by implementing the get_config method
    and the from_config class method.

這裡有一個自定義 layer 的例子,該 layer 將輸入和一個矩陣進行相乘:

class MyLayer(keras.layers.Layer):

  def __init__(self, output_dim, **kwargs):
    self.output_dim = output_dim
    super(MyLayer, self).__init__(**kwargs)

  def build(self, input_shape):
    shape = tf.TensorShape((input_shape[1], self.output_dim))
    # Create a trainable weight variable for this layer.
    self.kernel = self.add_weight(name='kernel',
                                  shape=shape,
                                  initializer='uniform',
                                  trainable=True)
    # Be sure to call this at the end
    super(MyLayer, self).build(input_shape)

  def call(self, inputs):
    return tf.matmul(inputs, self.kernel)

  def compute_output_shape(self, input_shape):
    shape = tf.TensorShape(input_shape).as_list()
    shape[-1] = self.output_dim
    return tf.TensorShape(shape)

  def get_config(self):
    base_config = super(MyLayer, self).get_config()
    base_config['output_dim'] = self.output_dim

  @classmethod
  def from_config(cls, config):
    return cls(**config)


# Create a model using the custom layer
model = keras.Sequential([MyLayer(10),
                          keras.layers.Activation('softmax')])

# The compile step specifies the training configuration
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs.
model.fit(data, targets, batch_size=32, epochs=5)

4. 訓練和評估

4.1 配置訓練過程

在模型構建完成後,通過呼叫 compile 方法來指定配置訓練過程。

model.compile(optimizer=tf.train.AdamOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

tf.keras.Model.compile 有三個重要的引數:

  • optimizer:訓練過程使用的優化方法。此引數通過 tf.train 模組的優化方法的例項來指定,比如:AdamOptimizerRMSPropOptimizerGradientDescentOptimizer
  • loss:訓練過程中使用的損失函式(通過最小化損失函式來訓練模型)。
    常用的有:(msecategorical_crossentropybinary_crossentropy)。
    指定方法:名稱 或 tf.keras.losses 模組中的函式。
  • metrics:訓練過程中,監測的指標(Used to monitor training)。
    指定方法:名稱 或 tf.keras.metrics 模組中的函式。

下面是配置模型訓練過程的一個例子:

# Configure a model for mean-squared error regression.
model.compile(optimizer=tf.train.AdamOptimizer(0.01),
              loss='mse',       # mean squared error
              metrics=['mae'])  # mean absolute error

# Configure a model for categorical classification.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.01),
              loss=keras.losses.categorical_crossentropy,
              metrics=[keras.metrics.categorical_accuracy])

4.2 輸入 Numpy 資料

對於小的資料集,可以直接使用 NumPy 格式的資料進行訓練、評估模型。模型使用 fit 方法直接使用 numpy 格式的資料訓練模型:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.fit(data, labels, epochs=10, batch_size=32)

tf.keras.Model.fit 有三個重要的引數:

  • epochs:訓練多少個 epochs
  • batch_size:指定 batch size。當時用 NumPy 格式資料時,模型會將資料切片成許多的小 batches,然後迭代這些batches。
    注意:如果資料不成正好分成如干個batch,最後一個 batch 可能會很小。
  • validation_data:當對模型進行原型研究時,您希望在某些驗證資料上輕鬆地監視其效能。
    通過這個引數(a tuple of inputs and labels)允許模型在每個 epoch 結束後,以推理模式在指定的資料集上計算並顯示損失和評價指標。

下面是一個使用 validatation_data 的例子:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

val_data = np.random.random((100, 32))
val_labels = np.random.random((100, 10))

model.fit(data, labels, epochs=10, batch_size=32,
          validation_data=(val_data, val_labels))

4.3 輸入 tf.data.datasets

# Instantiates a toy dataset instance:
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)
dataset = dataset.repeat()

# Don't forget to specify `steps_per_epoch` when calling `fit` on a dataset.
model.fit(dataset, epochs=10, steps_per_epoch=30)

這裡,fit 方法用 steps_per_epoch 引數來判斷訓練到第多少個 epoch 了。

Dataset API 也可以用於評估:

dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32).repeat()

val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
val_dataset = val_dataset.batch(32).repeat()

model.fit(dataset, epochs=10, steps_per_epoch=30,
          validation_data=val_dataset,
          validation_steps=3)

4.4 評估 和 預測

tf.keras.Model.evaluatetf.keras.Model.predict 能夠使用 NumPy 資料 和 tf.data.Dataset 資料。

以下面的方式進行評估:

model.evaluate(x, y, batch_size=32)

model.evaluate(dataset, steps=30)

以下面的方式進行預測:

model.predict(x, batch_size=32)

model.predict(dataset, steps=30)

5. 回撥(Callbacks)

回撥用來在訓練過程中,自定義、擴充套件模型的行為(A callback is an object passed to a model to customize and extend its behavior during training)。你可以編寫自定義 callback,也可以使用 tf.keras.callbacks 模組內建的 callback。

tf.keras.callbacks 內建的 callback 有:

  • tf.keras.callbacks.ModelCheckpoint:定期儲存 checkpoints。
  • tf.keras.callbacks.LearningRateScheduler:動態改變學習速率。
  • tf.keras.callbacks.EarlyStopping:當驗證集上的效能不再提高時,終止訓練。
  • tf.keras.callbacks.TensorBoard:使用 TensorBoard 監測模型的行為。

為了使用一個 tf.keras.callbacks.Callback,需要將它傳遞給模型的 fit 方法:

callbacks = [
  # Interrupt training if `val_loss` stops improving for over 2 epochs
  keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
  # Write TensorBoard logs to `./logs` directory
  keras.callbacks.TensorBoard(log_dir='./logs')
]
model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
          validation_data=(val_data, val_targets))

6. 模型的儲存和恢復

6.1 只儲存引數(Weights only)

使用 tf.keras.Model.save_weights 來儲存和載入模型的 weights:

# Save weights to a TensorFlow Checkpoint file
model.save_weights('./my_model')

# Restore the model's state,
# this requires a model with the same architecture.
model.load_weights('my_model')

預設情況下,這會以 TensorFlow checkpoint 格式儲存模型的 weights。weights 也可以儲存為 HDF5 格式(Keras 預設的儲存格式):

# Save weights to a HDF5 file
model.save_weights('my_model.h5', save_format='h5')

# Restore the model's state
model.load_weights('my_model.h5')

6.2 只儲存模型(Configuration only)

一個模型的 configuration 可以被儲存,序列化過程中不包含任何 weights。儲存的 configuration 可以用來重新建立、初始化出相同的模型,即使沒有模型原始的定義程式碼。Keras 支援 JSON,YAML 序列化格式:

# Serialize a model to JSON format
json_string = model.to_json()

# Recreate the model (freshly initialized)
fresh_model = keras.models.from_json(json_string)

# Serializes a model to YAML format
yaml_string = model.to_yaml()

# Recreate the model
fresh_model = keras.models.from_yaml(yaml_string)

注意:Subclassed models 是不可序列化的,因為它們的結構是在 Python 程式碼內的 call 方法裡定義的。

6.3 整個模型(Entire model)

整個模型可以被儲存成一個檔案(同時包含weights、configuration,甚至optimizer’s configuration)。這允許你去 checkpoint 一個模型、從 checkpoint 中模型所處狀態恢復訓練,而不需要原始的程式碼:

# Create a trivial model
model = keras.Sequential([
  keras.layers.Dense(10, activation='softmax', input_shape=(32,)),
  keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(data, targets, batch_size=32, epochs=5)


# Save entire model to a HDF5 file
model.save('my_model.h5')

# Recreate the exact same model, including weights and optimizer.
model = keras.models.load_model('my_model.h5')

7. Eager execution

Eager execution 是一個即時執行的程式設計環境(圖的定義和執行是同步的,可以動態的更改圖)。Keras 不支援動態圖,但 tf.keras 支援,並且在程式檢查和除錯過程中非常有用。

tf.keras所有的模型構建 API 相容 eager execution。並且,在編寫 model subclassingcustom layers 時使用 eager execution,好處多多。

8. 分散式

注意:

1. 從 TF 1.11.0 開始,tf.keras 中的 Modelfitevaluatepredict 方法開始支援 multi-GPU 分散式。
2. 從TF 1.11.0 開始,tf.estimator 開始支援 multi-worker 分散式。

8.1 Estimators

Estimators API 被用來在分佈時環境訓練模型。Estimator API 旨在大型資料集的分散式訓練,該 API 能夠匯出工業生產可用的模型。

一個 tf.keras.Model 可以用 tf.estimator API 來訓練(通過 tf.keras.estimator.model_to_estimator 將模型轉為一個 tf.estimator.Estimator 物件)。詳情見 Creating Estimators from Keras models

model = keras.Sequential([layers.Dense(10,activation='softmax'),
                          layers.Dense(10,activation='softmax')])

model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

estimator = keras.estimator.model_to_estimator(model)

8.2 多 GPU

tf.keras 模型可以通過 tf.contrib.distribute.DistributionStrategy 在多個 GPU 上執行。這個 API 在幾乎不需要更改程式碼的情況下,實現在多個 GPU 上的分散式訓練。

當前,tf.contrib.distribute.MirroredStrategy 是唯一支援的分散式策略。MirroredStrategy 對圖進行復制,以同步的方式訓練,並且梯度最後聚集在一個機器上。

為了使用 DistributionStrategy with Keras,首先用 tf.keras.estimator.model_to_estimatortf.keras.Model 轉化為一個 tf.estimator.Estimator,然後訓練轉化來的estimator。

下面的例子在一個機器的多個 GPU 上實現了 tf.keras.Model 的訓練。

首先,定義一個簡單的模型:

model = keras.Sequential()
model.add(keras.layers.Dense(16, activation='relu', input_shape=(10,)))
model.add(keras.layers.Dense(1, activation='sigmoid'))

optimizer = tf.train.GradientDescentOptimizer(0.2)

model.compile(loss='binary_crossentropy', optimizer=optimizer)
model.summary()

定義輸入 pipeline。input_fn 返回一個 tf.data.Dataset 物件,該物件用來將資料傳給多個裝置,每一個裝置處理一個 batch 的一個 slice。

def input_fn():
  x = np.random.random((1024, 10))
  y = np.random.randint(2, size=(1024, 1))
  x = tf.cast(x, tf.float32)
  dataset = tf.data.Dataset.from_tensor_slices((x, y))
  dataset = dataset.repeat(10)
  dataset = dataset.batch(32)
  return dataset

接下來,建立一個 tf.estimator.RunConfig 並設定 train_distribute 引數為 tf.contrib.distribute.MirroredStrategy 例項。當建立 MirroredStrategy 時,你可以指定一個裝置列表 或 通過 num_gpus
引數設定 GPU 的數量。預設使用所有的 GPU。


            
           

相關推薦

TensorFlow Keras 官方教程 * * * * *

TensorFlow版本:1.10.0 > Guide > Keras Keras 簡介 Keras 是建立和訓練深度學習模型的高階 API。它被用於快速原型、高階研究和生產。Keras 具有三個主要優點: 好用的 API Keras API

Tensorflow keras入門教程

目錄 1、Tensorflow與Keras 2、安裝內建Keras的Tensorflow 3、Tensorflow內建的Keras教程 3.1、匯入tf.keras 3.2、建立一個簡單的模型 3.2.1、順序模型

教程 | Tensorflow keras 極簡神經網路構建與使用

Tensorflow keras極簡神經網路構建教程 Keras介紹Keras (κέρας) 在希臘語中意為號角,它來自古希臘和拉丁文學中的一個文學形象。釋出於2015年,是一套高階API框架,其預設的backend是tensorflow,但是可以支援CNTK、Theano、MXNet作為backend執

tensorflow 檢查點和模型,儲存與恢復使用,官方教程(一)

檢查點:這種格式依賴於建立模型的程式碼。SavedModel:這種格式與建立模型的程式碼無關。示例程式碼本文件依賴於 TensorFlow 使用入門中詳細介紹的同一個鳶尾花分類示例。要下載和訪問該示例,請執行下列兩個命令:git clone https://github.co

Win10系統Anaconda+TensorFlow+Keras 環境搭建教程

紅色石頭的個人網站:redstonewill.com 前天我在公眾號推薦了《Python Deep Learning》這本書。該書是由 Keras 作者寫的,所以全書基本圍繞著 Keras 講深度學習的各種實現,從 CNN,RNN 到 GAN 等,偏入門,但理論和實戰部

TensorFlow官方教程《Neural Networks and Deep Learning》譯(第一章)

– 更新中 成果預展示 如果你能堅持閱讀完本章, 你可以獲得如下的成果: 上圖中的命令列視窗輸出為: Epoch 0: 9095 / 10000 Epoch 1: 9213 / 10000 Epoch 2: 9299 / 10000 E

TensorFlow官方教程學習筆記(五)——前饋神經網路

本文主要是在TensorFlow上搭建一個前饋神經網路(feed-forward neural network)來對TensorFlow的運作方式進行簡單介紹。 程式碼在\examples\tutorials\mnist\中,主要使用兩個檔案:mnist.py和fully

win10+anaconda+tensorflow+keras環境搭建教程(CPU版)

之前的電腦裝的是32位的anaconda的python2.7。幾天為了能把tensorflow跑起來,順便玩玩cnn,就重新把環境配置了下。 安裝anaconda 建議版本選擇python3.5的64位,版本號應該是4.2。然後點選安裝,沒太多技

TensorFlow官方教程學習筆記(一)——起步

TensorFlow可以拆成兩個詞:Tensor(張量)和Flow(流),Tensor代表最底層的資料結構,每一個Tensor可以簡易的理解為一個多維陣列,類似於Caffe中的Blob,不過與Blob不同的是,對於一張圖片,Tensor的四個維度分別是[batch, h

TensorFlow零基礎入門教程(二)之谷歌官方教程

其實內容有一定難度,不適合入門資料,同樣的內容可以講的很簡單,需要一定的知識儲備。 使用 TensorFlow 的基本步驟 學習目標: * 學習基本的 TensorFlow 概念 * 在 TensorFlow 中使用 LinearRegres

TensorFlow官方教程學習筆記之2-用於機器學習初學者學習的MNIST資料集(MNIST For ML Beginners)

1.資料集 MNIST是機器視覺入門級的資料集 2.演算法 1)核心 迴歸(Regression)演算法: 2)代價函式 交叉熵(cross-entropy): 3)優化 梯度下降法 3.程式碼 # Copyright 2

Windows64位安裝GPU版TensorFlow 0.12,Power Shell下輸入:安裝Tensorflow的全教程

unless 設置環境變量 log api err 化工 查看 aid nbsp 推薦使用powershell,只需要在cmd指令窗口輸入powershell即可 下載64位Python3.5(一定要3.5!!)可以通過Python 3.5 from python.org

RabbitMQ官方教程一 "Hello World!"

tps rabbit 官方教程 blank python.h targe world target rabbitmq https://zhuanlan.zhihu.com/p/24335916 https://www.rabbitmq.com/tutorials/tutor

Unity 官方教程 學習

mas variables ber item term media nim als -m Interface & Essentials Using the Unity Interface 1.Interface Overview https://unity3d.co

MySQL官方教程及各平臺的安裝教程和配置詳解入口

www 官方 apt源 nbsp chrom 版本選擇 rom gui apt 官方文檔入口: https://dev.mysql.com/doc/ 一般選擇MySQL服務器版本入口: https://dev.mysql.com/doc/refman/en/

Elasticsearch: 權威指南(官方教程

span spa art agg current .html mode ide gui 《Elasticsearch 權威指南》中文版 序言 前言 基礎入門 深入搜索 處理人類語言 聚合 地理位置 數據建模 管理、監控和部署

Hadoop MapReduce 官方教程 -- WordCount示例

get pre red oop hadoop apache tor ria pac Hadoop MapReduce 官方教程 -- WordCount示例: http://hadoop.apache.org/docs/r1.0.4/cn/mapred_tutorial.h

[教程10]TensorFlow線性模型教程

了解 air into tip 必須 輸出 ros 自己的 rmi [教程10]TensorFlow線性模型教程 在本教程中,我們將使用TensorFlow中的tf.estimator API來解決二進制分類問題:根據年齡,性別,教育和職業(特征)等個人的普查數據,我們將嘗

TensorFlow入門必讀教程,拿走不謝!

活性 一起 操作系統 得到 haskell 開源 ask 服務 好的 TensorFlow 是一個開源的深度學習框架,於 2015 年末發布後,它成為了在全球得到最廣泛采用的深度學習框架之一。 深度學習神經網絡通常包含許多層。它們使用多維數組在不同層之間傳輸數據或執行操作。

java 8編程入門官方教程pdf

喜歡 語言 程序 ber 下載地址 ui框架 施密特 spa bsp 下載地址:網盤下載 ava 8編程入門官方教程第6版pdf是為java學習者們打造的學習資料,針對新版JavaSE8對內容進行了全面更新。在暢銷書作者Herbert Schildt(施密特)的幫助下,可