1. 程式人生 > >Tensorflow實戰學習(三十八)【實現估值網路】

Tensorflow實戰學習(三十八)【實現估值網路】

Q-Learning,學習Action對應期望值(Expected Utility)。1989年,Watkins提出。收斂性,1992年,Watkins和Dayan共同證明。學習期望價值,從當前一步到所有後續步驟,總期望獲取最大價值(Q值、Value)。Action->Q函式,最佳策略,在每個state下,選擇Q值最高的Action。不依賴環境模型。有限馬爾科夫決策過程(Markov Dectision Process) ,Q-Learning被證明最終可以找到最優策略。

Q-Learning目標,求解函式Q(st,at),根據當前環境狀態,估算Action期望價值。Q-Learning訓練模型,以(狀態、行為、獎勵、下一狀態)構成元組(st,at,rt+1,st+1)樣本訓練,st當前狀態,at當前狀態下執行action,rt+1執行Action後獲得獎勵,st+1下一狀態,(當前狀態,行動,獎勵,下一狀態)。特徵(st,at)。學習目標(期望價值) rt+1+γ·maxaQ(st+1,a),當前Action獲得Reward,加下一步可獲得最大期望價值,當前狀態行動獎勵,加下一狀態行動最大期望價值。學習目標包含Q-Learning函式本身,遞迴求解。下一步可獲最大期望價值乘γ(衰減係數discount factor),未來獎勵的學習權重。discount factor 0,模型學習不到任何未來獎勵資訊,變短視,只關注當前利益。discount factor >= 1,演算法可能無法收斂,期望價值不斷累加沒有衰減(discount),期望價值發散。discount factor一般比1稍小。Qnew(st,at)<-(1-α)·Qold(st,at)+α·(rt+1+γ·maxaQ(st+1,a)),Q-Learning學習過程式子。舊Q-Learning函式Qold(st,at),向學習目標(當前獲得Reward加下一步可獲得最大期望價值),按較小學習速率α學習,得到新Q-Learning函式Qnew(st,at)。學習速率決定新獲取樣本資訊覆蓋率前掌握到資訊比率,通常設較小值,保證學習過程穩定,確保最後收斂性。Q-Learning需要初始值Q0,比較高初始值,鼓勵模型多探索。

學習Q-Learning模型用神經網路,得到模型是估值網路。用比較深的神經網路,就是DQN。Google DeepMind,《Nature》論文,《Human-level control through deep reinforcement learning》提出。DeepMind用DQN建立達到人類專家水平玩Atari2600系列遊戲Agent。

state of the art DQN Trick。第一個Trick。DQN引入卷積層。模型通過Atari遊戲視訊影象瞭解環境資訊並學習策略。DQN需要理解接收影象,具有影象識別能力。卷積神經網路,利用可提取空間結構資訊卷積層抽取特徵。卷積層提取影象中重要目標特徵傳給後層做分類、迴歸。DQN用卷積層做強化學習訓練,根據環境影象輸出決策。

第二個Trick。Experience Replay。深度學習需要大量樣本,傳統Q-Learning online update方法(逐一對新樣本學習)不適合DQN。增大樣本,多個epoch訓練,影象反覆利用。Experience Replay,儲存Agent Experience樣本,每次訓練隨機抽取部分樣本供網路學習。穩定完成學習任務,避免短視只學習最新接觸樣本,綜合反覆利用過往大量樣本學習。建立儲存Experience快取buffer,儲存一定量較新樣本。容量滿了,用新樣本替換最舊樣本,保證大部分樣本相近概率被抽到。不替換舊樣本,訓練過程被抽到概率永遠比新樣本高很多。每次需要訓練樣本,直接從buffer隨機抽取一定量給DQN訓練,保持樣本高利用率,讓模型學習到較新樣本。

第三個Trick。用第二個DQN網路輔助訓練,target DQN,輔助計算目標Q值,提供學習目標公式裡的maxaQ(st+1,a)。兩個網路,一個製造學習目標,一個實際訓練,讓Q-Learning訓練目標保持平穩。強化學習 Q-Learning學習目標每次變化,學習目標分部是模型本身輸出,每次更新模型引數會導致學習目標變化,更新頻繁幅度大,訓練過程會非常不穩定、失控,DQN訓練會陷入目標Q值與預測Q值反饋迴圈(陷入震盪發散,難收斂)。需要穩定target DQN輔助網路計算目標Q值。target DQN,低頻率、緩慢學習,輸出目標Q值波動較小,減小訓練過程影響。

第4個Trick。Double DQN。DeepMind 《Deep Reinforcement Learning with Double Q-Learning》。傳統DQN高估Action Q值,高估不均勻,導致次優Action被高估超過最優Action。target DQN 負責生成目標Q值,先產生Q(st+1,a),再通過maxa選擇最大Q值。Double DQN,在主DQN上通過最大Q值選擇Action,再獲取Action在target DQN Q值。主網選擇Action,targetDQN生成Action Q值。被選擇Q值,不一定總是最大,避免被高估次優Action總是超過最優Action,導致發現不了真正最好Action。學習目標公式:Target=rt+1+γ·Qtarget(st+1,argmaxa(Qmain(st+1,a)))。

第5個Trick。Dueling DQN。Google 《Dueling Network Architectures for Deep Reinforcement Learning》。Dueling DQN,Q值函式Q(st,at)拆分,一部分靜態環境狀態具有價值V(st),Value;另一部分動態選擇Action額外帶來價值A(at),Advantage。公式,Q(st,at)=V(st)+A(at)。網路分別計算環境Value和選擇Action Advantage。Advantage,Action與其他Action比較,零均值。網路最後,不再直接輸出Action數量Q值,輸出一個Value,及Action數量 Advantage值。V值分別加到每個Advantage值上,得最後結果。讓DQN學習目標更明確,如果當前期望價值主要由環境狀態決定,Value值大,所有Advantage波動不大;如果期望價值主要由Action決定,Value值小,Advantage波動大。分解讓學習目標更穩定、精確,DQN對環境狀態估計能力更強。

實現帶Trick DQN。任務環境 GridWorld導航類水言糹工。GridWorld包含一個hero,4個goal,2個fire。控制hero移動,每次向上、下、左、右方向移動一步,多觸碰goal(獎勵值1),避開fire(獎勵值-1)。遊戲目標,限度步數內拿到最多分數。Agent 直接通過GridWorld影象學習控制hero移動最優策略。

建立GridWorld任務環境。載入依賴庫,itertools迭代操作,scipy.misc、matplotlib.pyplot繪圖,訓練時間長,os定期儲存模型檔案。

建立環境內物體物件class。環境物體屬性,coordinates(x,y座標)、size(尺寸)、intensity(亮度值)、channel(RGB顏色通道)、reward(獎勵值)、name(名稱)。

建立GridWorld環境class,初始化方法只傳入引數環境size。環境長、寬為輸入size,環境Action Space設4,初始化環境物體物件列表。self.reset()方法重置環境,得到初始observation(GridWorld影象),plt.imshow展示observation。

定義環境reset方法。建立所有GridWorld物體,1個hero(使用者控制物件)、4個goal(reward 1)、2個fire(reward -1),新增到物體物件列表self.objects。self.newPosition()建立物體位置,隨機選擇沒有被佔用新位置。物有物體size、intensity 1,hero channel 2(藍色),goal channel 1(綠色),fire channel 0(紅色)。self.renderEnv()繪製GridWorld影象,state。

實現移動英雄角色方法,傳入值0、1、2、3四個數字,分別代表上、下、左、右。函式根據輸入操作英雄移動。如果移動該方向會導致英雄出界,不會進行任何移動。

定義newPosition方法,選擇一個跟現有物體不衝突位置。itertools.product方法得到幾個變數所有組合,建立環境size允許所有位置集合points,獲取目前所有物體位置集合currentPositions,從points去掉currentPositions,剩下可用位置。np.random.choice隨機抽取一個可用位置返回。

定義checkGoal函式。檢查hero是否觸碰goal、fire。從objects獲取hero,其他物體物件放到others列表。編歷others列表,如果物體和座標與hero完全一致,判定觸碰。根據觸碰物體銷燬,self.newPosition()方法在隨機位置重新生成物體,返回物體reward值(goal 1,fire -1)。

建立長宛size+2、顏色通道數 3 圖片。初始值全1,代表全白色。最外圈內部畫素顏色值全部賦0,代表黑色。遍歷物體物件列表self.objects,設定物體亮度值。scipy.misc.imresize將影象從原始大小resize 84x84x3尺寸,正常遊戲影象尺寸。

定義GridWorld環境執行一步Action方法。輸入引數Action,self.moveChart(action)移動hero位置,self.checkGoal()檢測hero是否觸碰物體,得到reward、done標記。self.renderEnv獲取環境影象state,返回state、reward、done。

呼叫gameEnv類初始化方法,設定size 5,建立5x5大小GridWorld環境,每次建立GridWorld環境隨機生成。小尺寸環境相對容易學習,大尺寸較難,訓練時間更長。

設計DQN(Deep Q-Network)網路。使用卷積層,可以直接從環境原始畫素學習策略。輸入scalarInput,扁平化長為84x84x3=21168向量,恢復成[-1,84,84,3]尺寸圖片ImageIn。tf.contrib.layers.convolution2d建立第1個卷積層,卷積核尺寸8x8,步長4x4,輸出通道數(filter數量)32,padding模型VALID,bias初始化器空。用4x4步長和VALID模型padding,第1層卷積輸出維度20x20x32。第2層卷積尺寸4x4,步長2x2,輸出通道數64,輸出維度9x9x64。第3層卷積尺寸3x3,步長1x1,輸出通道數64,輸出維度7x7x64。第4層卷積尺寸7x7,步長1x1,輸出通道數512,空間尺寸只允許在一個位置卷積,,輸出維度1x1x512。

tf.split(),第4個卷積層輸出conv4平均拆分兩段,streamAC、streamVC,Dueling DQN Advantage Function(Action帶來的價值)和Value Function(環境本身價值)。tf.split函式第2引數代表要拆分成幾段。第3引數代表要拆分幾個維度。tf.contrib.layers.flatten將streamAC和streamVC轉遍平的steamA和steamV。建立streamA和streamV線性全連線層引數AW和VW。tf.random_normal初始化權重,tf.matmul做全連線層矩陣乘法,得到self.Advantage和self.Value。Advantage針對Action,輸出數量為Action數量。Value針對環境統一的,輸出數量 1。Q值由Value、advantage複合成,Value加上減少均值Advantage。Advantage減去均值操作 tf.subtract,均值計算tf.reduce_mean函式(reduce_indices 1,代表Action數量維度)。最後輸出Action,Q值最大Action,tf.argmax。

定義Double DQN目標Q值targetQ輸入placeholder,Agent動作actions輸入placeholder。計算目標Q值,action由主DQN選擇,Q值由輔助target DQN生成。計算預測Q值,scalar形式actions轉onehot編碼形式,主DQN生成的Qout乘以actions_onehot,得預測Q值(Qout和actions都來自主DQN)。

定義loss,tf.square、tf.reduce_mean計算targetQ和Q均方誤差,學習速率1e-4 Adam優化器優化預測Q值和目標Q值偏差。

實現Experience Replay策略。定義experience_buffer class。初始化定義buffer_size儲存樣本最大容量,建立buffer列表。定義向經buffer新增元素方法。如果超過buffer最大容量,清空最早樣本,列表末尾新增新元素。定義樣本抽樣方法,用random.sample()函式隨機抽取一定數量樣本。

定義84x84x3 states扁平化 1維向量函式processState,方便後面堆疊樣本。

updateTargetGraph函式,更新target DQN模型引數(主DQN用DQN class self.updateModel方法更新模型引數)。輸入變數tfVars,TensorFlow Graph全部引數。tau,target DQN向主DQN學習的速率。函式updateTargetGraph取tfVars前一半引數,主DQN模型引數。再令輔助targetDQN引數朝向主DQN引數前進很小比例(tau,0.001),target DQN緩慢學習主DQN。訓練時,目標Q值不能在幾次迭代間波動太大,訓練非常不穩定、失控,陷入目標Q值和預測Q值反饋迴圈。需要穩定目標Q值訓練網路,緩慢學習target DQN網路輸出目標Q值,主網路優化目標Q值和預測Q值間loss,target DQN跟隨主DQN緩慢學習。函式updateTargetGraph建立更新target DQN模型引數操作,函式updateTarget執行操作。

DQN網路訓練過程引數。batch_size,每次從experience buffer獲取樣本數,32。更新頻率update_freq,每隔多少step執行一次模型引數更新,4。Q值衰減係數(discount factor)γ,0.99。startE起始執行隨機Action概率。endE最終執行隨機Action概率。anneling_steps從初始隨機概率降到最終隨機概率所需步數。num_episodes總共多少次GridWorld環境試驗。pre_train_steps正式用DQN選擇Action前進行多少步隨機Action測試。max_epLength每個episode進行多少步Action。load_model是否讀取之前訓練模型。path模型儲存路徑。h_size是DQN網路最後全連線層隱含節點數。tau是target DQN向主DQN學習速率。

Qnetwork類初始化mainQN和輔助targetQN。初始化所有模型引數。trainables獲取所有可訓練引數。updateTargetGraph建立更新target DQN模型引數操作。

experience_buffer建立experience replay class,設定當前隨機Action概率e,計算e每一步衰減值stepDrop。初始化儲存每個episode的reward列表rList,總步數total_steps。建立模型訓練儲存器(Saver)檢查儲存目錄是否存在。

建立預設Session,如果load_model標誌True,檢查模型檔案路徑checkpoint,讀取載入已儲存模型。執行引數初始化操作,執行更新targetQN模型引數操作。建立GridWorld試驗迴圈,建立每個episode內部experience_buffer,內部buffer不參與當前迭代訓練,訓練只使用之前episode樣本。初始化環境得第一個環境資訊s,processState()函式扁平化。初始化預設done標記d、episode內總reward值rAll、episode內步數j。

建立內層迴圈,每次迭代執行Action。總步數小於pre_train_steps,強制用隨機Action,只從隨機Action學習,不強化過程。達到pre_train_steps,保留較小概率隨機選擇Action。不隨機選擇Action,傳入當前狀態s給主DQN,預測得到應該執行Action。env.step()執行一步Action,得到接下來狀態s1、reward、done標記。processState對s1扁平化處理,s、a、r、s1、d傳入episodeBuffer儲存。

總步數超過pre_train_steps,持續降低隨機選擇Action概率e,直到最低值endE。每當總步數達到update_freq整數部,進行一次訓練,模型引數更新。從myBuffer中sample出一個batch_size樣本。訓練樣本第3列資訊,下一狀態s1,傳入mainQN,執行main.predict,得到主模型選擇Action。s1傳入輔助targetQN,得到s1狀態下所有Action的Q值。mainQN輸出Action ,選擇targetQN輸出Q,得到doubleQ。兩個DQN網路把選擇Action和輸出Q值兩個操作分隔開,Double DQN。訓練樣本第2列資訊,當前reward,加doubleQ乘以衰減係數γ,得到學習目標targetQ。傳入當前狀態s,學習目標targetQ和實際採取Action,執行updateTarget函式,執行targetQN模型引數更新(緩慢向mainQN學習)。完整完成一次訓練過程。每個step結束,累計當前這步獲取reward,更新當前狀態為下一步試驗做準備。如果done標記為True,直接中斷episode試驗。

episode內部episodeBuffer新增到myBuffer,作以後訓練抽樣資料集。當前episode reward新增到rList。每25個episode展示平均reward值。每1000個episode或全部訓練完成,儲存當前模型。

初始200個episode內,完全隨機Action的前10000步內,平均可以獲得reward在2附近,基礎baseline。

訓練最後episode輸出,平均reward 22,非常大提升。

計算每100個episode平均reward,plt.plot展示reward變化趨勢。從第1000個episode開始,reward快速提升,到第4000個episode基本達到高峰,後面進入平臺期,提升不大。

    import numpy as np
    import random
    import tensorflow as tf
    import os
    %matplotlib inline
    from gridworld import gameEnv
    env = gameEnv(size=5)
    class Qnetwork():
        def __init__(self,h_size):
            #The network recieves a frame from the game, flattened into an array.
            #It then resizes it and processes it through four convolutional layers.
            self.scalarInput =  tf.placeholder(shape=[None,21168],dtype=tf.float32)
            self.imageIn = tf.reshape(self.scalarInput,shape=[-1,84,84,3])
            self.conv1 = tf.contrib.layers.convolution2d( \
                inputs=self.imageIn,num_outputs=32,kernel_size=[8,8],stride=[4,4],padding='VALID', biases_initializer=None)
            self.conv2 = tf.contrib.layers.convolution2d( \
                inputs=self.conv1,num_outputs=64,kernel_size=[4,4],stride=[2,2],padding='VALID', biases_initializer=None)
            self.conv3 = tf.contrib.layers.convolution2d( \
                inputs=self.conv2,num_outputs=64,kernel_size=[3,3],stride=[1,1],padding='VALID', biases_initializer=None)
            self.conv4 = tf.contrib.layers.convolution2d( \
                inputs=self.conv3,num_outputs=512,kernel_size=[7,7],stride=[1,1],padding='VALID', biases_initializer=None)

            #We take the output from the final convolutional layer and split it into separate advantage and value streams.
            self.streamAC,self.streamVC = tf.split(self.conv4,2,3)
            self.streamA = tf.contrib.layers.flatten(self.streamAC)
            self.streamV = tf.contrib.layers.flatten(self.streamVC)
            self.AW = tf.Variable(tf.random_normal([h_size//2,env.actions]))
            self.VW = tf.Variable(tf.random_normal([h_size//2,1]))
            self.Advantage = tf.matmul(self.streamA,self.AW)
            self.Value = tf.matmul(self.streamV,self.VW)

            #Then combine them together to get our final Q-values.
            self.Qout = self.Value + tf.subtract(self.Advantage,tf.reduce_mean(self.Advantage,reduction_indices=1,keep_dims=True))
            self.predict = tf.argmax(self.Qout,1)

            #Below we obtain the loss by taking the sum of squares difference between the target and prediction Q values.
            self.targetQ = tf.placeholder(shape=[None],dtype=tf.float32)
            self.actions = tf.placeholder(shape=[None],dtype=tf.int32)
            self.actions_onehot = tf.one_hot(self.actions,env.actions,dtype=tf.float32)

            self.Q = tf.reduce_sum(tf.multiply(self.Qout, self.actions_onehot), reduction_indices=1)

            self.td_error = tf.square(self.targetQ - self.Q)
            self.loss = tf.reduce_mean(self.td_error)
            self.trainer = tf.train.AdamOptimizer(learning_rate=0.0001)
            self.updateModel = self.trainer.minimize(self.loss)

    class experience_buffer():
        def __init__(self, buffer_size = 50000):
            self.buffer = []
            self.buffer_size = buffer_size

        def add(self,experience):
            if len(self.buffer) + len(experience) >= self.buffer_size:
                self.buffer[0:(len(experience)+len(self.buffer))-self.buffer_size] = []
            self.buffer.extend(experience)

        def sample(self,size):
            return np.reshape(np.array(random.sample(self.buffer,size)),[size,5])

    def processState(states):
        return np.reshape(states,[21168])

    def updateTargetGraph(tfVars,tau):
        total_vars = len(tfVars)
        op_holder = []
        for idx,var in enumerate(tfVars[0:total_vars//2]):
            op_holder.append(tfVars[idx+total_vars//2].assign((var.value()*tau) + ((1-tau)*tfVars[idx+total_vars//2].value())))
        return op_holder
    def updateTarget(op_holder,sess):
        for op in op_holder:
            sess.run(op)
    batch_size = 32 #How many experiences to use for each training step.
    update_freq = 4 #How often to perform a training step.
    y = .99 #Discount factor on the target Q-values
    startE = 1 #Starting chance of random action
    endE = 0.1 #Final chance of random action
    anneling_steps = 10000. #How many steps of training to reduce startE to endE.
    num_episodes = 10000#How many episodes of game environment to train network with.
    pre_train_steps = 10000 #How many steps of random actions before training begins.
    max_epLength = 50 #The max allowed length of our episode.
    load_model = False #Whether to load a saved model.
    path = "./dqn" #The path to save our model to.
    h_size = 512 #The size of the final convolutional layer before splitting it into Advantage and Value streams.
    tau = 0.001 #Rate to update target network toward primary network
    tf.reset_default_graph()
    mainQN = Qnetwork(h_size)
    targetQN = Qnetwork(h_size)
    init = tf.global_variables_initializer()
    trainables = tf.trainable_variables()
    targetOps = updateTargetGraph(trainables,tau)
    myBuffer = experience_buffer()
    #Set the rate of random action decrease. 
    e = startE
    stepDrop = (startE - endE)/anneling_steps
    #create lists to contain total rewards and steps per episode
    rList = []
    total_steps = 0
    #Make a path for our model to be saved in.
    saver = tf.train.Saver()
    if not os.path.exists(path):
        os.makedirs(path)
    #%%
    with tf.Session() as sess:
        if load_model == True:
            print('Loading Model...')
            ckpt = tf.train.get_checkpoint_state(path)
            saver.restore(sess,ckpt.model_checkpoint_path)
        sess.run(init)
        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
        for i in range(num_episodes+1):
            episodeBuffer = experience_buffer()
            #Reset environment and get first new observation
            s = env.reset()
            s = processState(s)
            d = False
            rAll = 0
            j = 0
            #The Q-Network
            while j < max_epLength: #If the agent takes longer than 200 moves to reach either of the blocks, end the trial.
                j+=1
                #Choose an action by greedily (with e chance of random action) from the Q-network
                if np.random.rand(1) < e or total_steps < pre_train_steps:
                    a = np.random.randint(0,4)
                else:
                    a = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:[s]})[0]
                s1,r,d = env.step(a)
                s1 = processState(s1)
                total_steps += 1
                episodeBuffer.add(np.reshape(np.array([s,a,r,s1,d]),[1,5])) #Save the experience to our episode buffer.

                if total_steps > pre_train_steps:
                    if e > endE:
                        e -= stepDrop

                    if total_steps % (update_freq) == 0:
                        trainBatch = myBuffer.sample(batch_size) #Get a random batch of experiences.
                        #Below we perform the Double-DQN update to the target Q-values
                        A = sess.run(mainQN.predict,feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,3])})
                        Q = sess.run(targetQN.Qout,feed_dict={targetQN.scalarInput:np.vstack(trainBatch[:,3])})
                        doubleQ = Q[range(batch_size),A]
                        targetQ = trainBatch[:,2] + y*doubleQ
                        #Update the network with our target values.
                        _ = sess.run(mainQN.updateModel, \
                            feed_dict={mainQN.scalarInput:np.vstack(trainBatch[:,0]),mainQN.targetQ:targetQ, mainQN.actions:trainBatch[:,1]})

                        updateTarget(targetOps,sess) #Set the target network to be equal to the primary network.
                rAll += r
                s = s1

                if d == True:
                    break

            #Get all experiences from this episode and discount their rewards.
            myBuffer.add(episodeBuffer.buffer)
            rList.append(rAll)
            #Periodically save the model.
            if i>0 and i % 25 == 0:
                print('episode',i,', average reward of last 25 episode',np.mean(rList[-25:]))
            if i>0 and i % 1000 == 0:
                saver.save(sess,path+'/model-'+str(i)+'.cptk')
                print("Saved Model")            
        saver.save(sess,path+'/model-'+str(i)+'.cptk')
    #%%
    rMat = np.resize(np.array(rList),[len(rList)//100,100])
    rMean = np.average(rMat,1)
    plt.plot(rMean)

參考資料:
《TensorFlow實戰》

相關推薦

Tensorflow實戰學習()實現網路

Q-Learning,學習Action對應期望值(Expected Utility)。1989年,Watkins提出。收斂性,1992年,Watkins和Dayan共同證明。學習期望價值,從當前一步到所有後續步驟,總期望獲取最大價值(Q值、Value)。Acti

Tensorflow實戰學習(四)實現Word2Vec

卷積神經網路發展趨勢。Perceptron(感知機),1957年,Frank Resenblatt提出,始祖。Neocognitron(神經認知機),多層級神經網路,日本科學家Kunihiko fukushima,20世紀80年代提出,一定程度視覺認知功能,啟發

Tensorflow實戰學習(四)多GPU並行

TensorFlow並行,模型並行,資料並行。模型並行根據不同模型設計不同並行方式,模型不同計算節點放在不同硬伯上資源運算。資料並行,比較通用簡便實現大規模並行方式,同時使用多個硬體資源計算不同batch資料梯度,彙總梯度全域性引數更新。 資料並行,多塊GPU

Android項目實戰):2017最新 將AndroidLibrary提交到JCenter倉庫(圖文教程)

success hub rdf fault 用戶 builds style config ocl 我們經常使用github上的開源項目,使用步驟也很簡單 比如: compile ‘acffo.xqx.xwaveviewlib:maven:1.0.0‘ 這裏就學習一下如何

易寶典——玩轉O365中的EXO服務 之 如何實現現有O365用戶郵箱與現有域用戶便捷集成

雲計算 Office 365 微軟 混合雲 企業集成 引子:本來該節應該講述關於“電子數據展示”相關的內容。但是,今晨突然收到一封關於Office 365與本地域用戶集成整合的咨詢郵件。因此,想到應該將博主在“Microsoft Tech Summit 2017微軟技術暨生態大會”的主題

ABP官方文件()AJAX API

6.6 ABP表現層 - AJAX API 6.6.2.1 AJAX操作問題 現代的應用經常會使用AJAX,尤其是單頁應用,幾乎是和伺服器通訊的唯一手段,執行AJAX通常會有以下步驟: 基本上:為了執行一個AJAX呼叫,首先你要在客戶端提供一個可供請

Tensorflow實戰學習()詞向量、維基百科語料庫訓練詞向量模型

詞向量嵌入需要高效率處理大規模文字語料庫。word2vec。簡單方式,詞送入獨熱編碼(one-hot encoding)學習系統,長度為詞彙表長度的向量,詞語對應位置元素為1,其餘元素為0。向量維數很高,無法刻畫不同詞語的語義關聯。共生關係(co-occurre

opencv學習影象的分水嶺演算法

分水嶺演算法主要根據影象梯度將影象分割成“山”和“谷”;一般影象噪聲經常干擾分水嶺演算法的分割,所以一般採用標記的方法來給分水嶺演算法提供灰度級參考,來更換的分割影象;從效果來說比普通的灰度閾值分割效果要好;演算法的具體原理和實現可參考網上的詳解;原函式及解釋:CV_EXPO

、100行python程式碼實現機器學習自動分類

現在朋友圈、公眾號、微博資訊應接不暇,以微信公眾號舉例,看技術極客是怎麼自動篩出自己想看的文章的,100行機器學習程式碼就能自動幫你歸好類,要想找出想看的和不想看的,你再也不用刷朋友圈了 準備工作 1. 準備一張mysql資料庫表,至少包含這些列:id、title(文章標題)、content(文章內

Tensorflow實戰學習(四)卷積層、啟用函式、池化層、歸一化層、高階層

CNN神經網路架構至少包含一個卷積層 (tf.nn.conv2d)。單層CNN檢測邊緣。影象識別分類,使用不同層型別支援卷積層,減少過擬合,加速訓練過程,降低記憶體佔用率。 TensorFlow加速所有不同類弄卷積層卷積運算。tf.nn.depthwise_c

WPF學習章 行為

  樣式提供了重用一組屬性設定的實用方法。它們為幫助構建一致的、組織良好的介面邁出了重要的第一步——但是它們也是有許多限制。   問題是在典型的應用程式中,屬性設定僅是使用者介面基礎結構的一小部分。甚至最基本的程式通常也需要大量的使用者介面程式碼,這些程式碼與應用程式的功能無關。在許多

JMeter學習)JMeter測試Java(二)

sets interval permsize int 文件 不同 時間 結果 argument 實例: 服務為:將輸入的兩個參數通過IO存入文件; 1、打開MyEclipse,編寫Java代碼 服務: package test; import java.io.F

Android實戰技巧之:Handler使用中可能引發的內存泄漏

sha 指向 ons har 引用 destroy 對象 from weak 問題描寫敘述 曾幾何時,我們用原來的辦法使用Handler時會有以下一段溫馨的提示: This Handler class should be static or le

Android的DatePicker和TimePicker-android學習之旅(

cursor ini lis drawable textview @+ type pin view DatePicker和TimePicker簡單介紹 DatePicker和TimePicker是從FrameLayout繼承而來。他們都是比較簡單的組件

社區問答第編寫高質量C程序代碼

lds smi c89 use amp href dff c程序 dbf NOJ的一道題 求助大神 Java爬蟲,信息抓取的實現 C++實現給多個變量傳值 指針定義成全局和定義在main中為什麽不一樣?定義在main中執行中止 cqj慰膛哦http://p.baidu.co

Linux學習總結()lamp之php擴展模塊安裝

lamp php php擴展模塊 php動態模塊是一個可以看的見的以.so結尾的文件,可以根據需要加載使用。靜態模塊跟隨php一起啟動,看不到文件。php一旦編譯完成,要想再增加一個功能模塊的話,要麽重新編譯php,要麽直接編譯一個擴展模塊,然後在php.ini中配置一下就可以被加載使用。/usr

Android項目實戰七):Activity管理及BaseActivity的實現

nbsp agen etc == tar fin email ted AD 原文:Android項目實戰(三十七):Activity管理及BaseActivity的實現Ps:7-10月 完成公司兩個app項目上架。漏掉的總結 開始慢慢補上。 一、寫一個Activit

用Vue來實現音樂播放器():歌詞滾動列表的問題

vue 三十八 pla -s toggle 情況 TP 解決辦法 暫停 1、頻繁切換歌曲時,歌詞會跳來跳去 原因: // 歌詞跳躍是因為內部有一個currentLyric對像內部有一些功能來完成歌詞的跳躍 //每個currentLyric能實現歌曲的播放跳到相應的位置 是

leetcode 簡單題 Excel表列名稱

itl span title 給定 取余 正整數 簡單 exc pre 給定一個正整數,返回它在 Excel 表中相對應的列名稱。 例如, 1 -> A 2 -> B 3 -> C ... 26 -> Z

機器學習筆記(二):TensorFlow實戰四(影象識別與卷積神經網路

1 - 卷積神經網路常用結構 1.1 - 卷積層 我們先來介紹卷積層的結構以及其前向傳播的演算法。 一個卷積層模組,包含以下幾個子模組: 使用0擴充邊界(padding) 卷積視窗過濾器(filter) 前向卷積 反向卷積(可選) 1.1