Day10-微信小程序實戰-交友小程序-實現刪除好友信息與子父組件間通信

回顧:上一次已經把消息的布局以及樣式做好了

效果圖:

 

 在removeList.js文件中,messageId就是發起這個消息的用戶了

先查看一下自定義組件的生命周期

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html

 lifetimes: {
    attached: function() {
      // 在組件實例進入頁面節點樹時執行
    },
    detached: function() {
      // 在組件實例被從頁面節點樹移除時執行
    },
  }

直接就是在lifttimes裏面進行定義的(直接就是在methods的同級的下面加上即可了)

因為要對用戶的信息進行渲染,就可以看成是一個一個的對象,所以就可以在removeLIst.js中定義一個對象

然後遇到的問題就和之前是一樣的了,就是我們得到的數據太多了,沒必要全部都要,可以選擇性的要,只需要頭像和昵稱

(所以就可以在get前面來一個field)

lifetimes: {
    attached: function () {
      // 一進來就會進行它了
      db.collection('users').doc(this.data.messageId)
      .field({
        userPhoto : true,
        nickName : true
      })
      .get().then((res)=>{
        this.setData({
            userMessage : res.data
        });
      });
    }
  }

這樣的話我們在這個頁面裏面就可以得到用戶的數據了,剩下的就是直接可以在wxml中用了

<!--components/removeList/removeList.wxml-->
<movable-area class="area">
     <movable-view direction="horizontal" class="view">{{ userMessage.nickName }}</movable-view>
     <image src="{{ userMessage.userPhoto }}" />
     <view class="delete">刪除</view>
 </movable-area>

效果圖:

 

 在之後設置刪除功能之前,先設置一下就是只要點擊了消息列表中用戶的頭像之後,就可以跳轉到這個用戶的詳情頁了

可以直接 在編輯個人信息的頁面 editUserInfo.wxml中COPY代碼  

在設置這個跳轉頁面的url的時候,因為同時要給這個url傳遞參數的,所以這個時候就要用大括號括起來了

<!--components/removeList/removeList.wxml-->
<movable-area class="area">
     <movable-view direction="horizontal" class="view">{{ userMessage.nickName }}</movable-view>
     <navigator url="{{'/pages/detail/detail?userId=' + userMessage._id}}" open-type="navigate">
     <image src="{{ userMessage.userPhoto }}" />
     </navigator>
     <view class="delete">刪除</view>
 </movable-area>

即可實現,點擊頭像跳轉到個人的詳情頁面

 

二、下面就是對刪除功能進行設計

一開始的就是,點擊了之後,要給用戶一個提示信息,讓用戶可以選擇是取消還是確定的,這裏用的是一個wx.showModel這樣一個內置的方法

 

所以就要另外的給“點擊了確定”加邏輯了,就要在微信開放文檔裏面細看這個API了

https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showModal.html

wx.showModal({
  title: '提示',
  content: '這是一個模態彈窗',
  success (res) {
    if (res.confirm) {
      console.log('用戶點擊確定')
    } else if (res.cancel) {
      console.log('用戶點擊取消')
    }
  }
})

把查到的賦值給list,然後在用數組的filter進行刪除即可了

通過fileter過濾之後,就是過濾初和我們不想要的東西,然後把這些東西再次賦值為list,然後我們把前後的list打印出來會發現:

 

 確實是過濾掉了的

 由於如果要刪掉的話,就設計了removeList這個組件和message這各頁面之間的通信了,並且是子組件像父組件,用到事件來做的

https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html

<!-- 當自定義組件觸發“myevent”事件時,調用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以寫成 -->
<component-tag-name bind:myevent="onMyEvent" />

所以在message.wxml中隊子組件remove-list設置

<remove-list wx:for="{{ userMessage }}" wx:key="{{index}}" messageId="{{ item }}"
     bindmyevent="onMyEvent"/> 
    

這樣事件監聽就寫好了,但是如何在組件中觸發呢,我們回到removelist.js中

繼續查看山脈的鏈接-微信開發文檔

Component({
  properties: {},
  methods: {
    onTap: function(){
      var myEventDetail = {} // detail對象,提供給事件監聽函數
      var myEventOption = {} // 觸發事件的選項
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})

在removelist.js中通過:

 this.triggerEvent('myevent',list) 

前面參數,要和在 message.wxml設置的 bindmyevent,後面的myevent對應上

第二個參數就是我們 過濾剩下的list

給message傳過去之後

  onMyEvent(ev){
  this.setData({
    userMessage : ev.detail
  });

通過這樣的設置出現了一個bug,就是我們刪除第一條信息的時候,直接把第二條刪掉了,第一條被留下來了

當我們查看數據庫的時候,留下來的就是第二條信息,但是在前端显示的是第一條信息留下,第二條信息沒了

要這樣修改:

onMyEvent(ev){
    this.setData({
      userMessage : []
    },()=>{
        this.setData({
          userMessage : ev.detail
        });
    });
  }
  

先賦值為空,之後再次調用removelist,再把過濾的數組進行賦值  

 

 

 也就是全部清空之後,再重新渲染的

 

 整個邏輯:

1、在數據庫中用戶的頭像和昵稱找到,然後獲取數據

 

2、點擊刪除按鈕的時候,彈出提示框,如果用戶點了缺點刪除的話,之後我們先查詢

 找到之後,把那個消息在message列表中過濾掉

 

 3、然後再重新的更新,之後就觸發子父通信,把更新之後的list傳給

 

4、父組件拿到removelist這組件的信息

 

 拿到就更新我們的列表,這樣的話列表就發送了變化了

 

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

【其他文章推薦】

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

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

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

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

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

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

Google 懸賞 3,000 萬,縮小逆變器體積至十分之一

 

對綠能產業相當關心的 Google,在分散式能源領域,當然也不會缺席。今年 5 月,Google 公布「小盒計畫(Little Box Challenge)」,若是有員工能研發出縮小版的逆變器,就能獲得 100 萬美元(約合新台幣 3,000 萬元)獎金。而最近 Google 將這項計畫對外開放,參賽者在 2015 年 7 月前都能報名參加,最後交由電機電子工程師學會(IEEE)評選出優勝者。

逆變器在綠能產業中扮演關鍵性的角色,舉凡連接太陽能板、風力發電機、電動車等電網裝置,都需要逆變器參與其中,而逆變器的主要用途就是把太陽能板接收能量後產生的直流電,轉換為交流電併入電網當中;電動車作為電力儲存裝置時,若要將電能輸出,也同樣必須藉由逆變器轉換為交流電併入電網。    
 

   
逆變器體積縮小有利微電網發展   然而,隨著屋頂太陽能板裝設越來越普遍,龐大的逆變器顯得笨重又不符合效益,這也是 Google 為何如此迫切希望大幅縮小逆變器的體積與重量的原因。   Google 的「小盒計畫」希望將逆變器體積縮為現在的十分之一,相當於一台小筆電的大小;每立方英吋的功率密度須超過 50 瓦特;轉換效率最低值至少為 95%;耐高溫性的部分,須可承受攝氏 60 度的高溫,其他標準則包括一些能讓逆變器與電網連結作用的規格限制。而綜結以上這些規格,最重要的,當然還是參賽者能否縮小逆變器的體積大小了。  
 

      假如能研發出小型逆變器,Google 希望能在偏遠地區打造低成本的微電網,或在停電時,能以電動車維持穩定電力供給,讓他們在綠能產業的佈局上,又多了一項投資。   在矽谷科技企業中,Google 對綠能的投資可說是最不手軟的一家,綠能涉獵範圍也最廣泛。就如先前《科技新報》提到的,過去 5 年內,Google 在太陽能與風能等綠能上的投資,已超過 10 億美元。除了持有「大西洋風能網」項目建設中 37.5 % 的股份、投資美國離岸風力發電骨幹計畫 50 億美元外,在電網上的參與也越來越活躍。   過去幾個月以來,Google 開發名為「顛覆電網(Bottom Up Grid)」的專案,陸續招募電力或電子工程師,希望能從最根本改善電力轉換系統。看來現在除了佈局綠能產業外,與綠能息息相關的電網系統,也成為 Google 改革的目標了。   本文全文授權自《科技新報》──  

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

新能源汽車利好消息層出不窮 下半年產銷量有望爆發式增長—第五屆新能源汽車峰會暨展覽會

中汽協發佈的最新資料顯示,今年上半年中國新能源汽車生產20692輛,銷售20477輛,同比分別增長2.3倍和2.2倍,產銷量已經超過去年全年的1.7萬輛。其中純電動汽車產銷分別完成12185輛和11777輛,插電式混合動力汽車產銷分別完成8507輛和8700輛。在新政頻發、充電基礎設施和電池產業鏈發展及車企爭奪多番力量推動下,新能源汽車下半年產銷量有望呈爆發式增長。

新政4連發護航

2014年初以來中國中央政府確定了40個新能源汽車示範城市或區域,預計未來2年內累計推廣規模將超過30萬輛。而且近期北京、上海、廣東、江蘇等9個示範區域的實施細則陸續落地。補貼政策從購車、用車、配套等多環節提升新能源汽車經濟性,驅動產業快速發展。

國家機關購買新能源汽車管理辦法發佈。中國中央政府門戶網站7月13日刊登消息,《政府機關及公共機構購買新能源汽車實施方案》(下稱《方案》)印發。主要內容包括,2014年至2016年,中央國家機關以及88個新能源汽車推廣應用城市的政府機關及公共機構購買的新能源汽車占當年配備更新總量的比例不低於30%,以後逐年提高。方案明確規定至2016年公車採購中購買的新能源汽車占當年配備更新總量的比例不低於30%,這意味著新能源車迎來超過300億元的市場份額。《方案》的出臺將加快政府機關採購新能源汽車的速度。

國務院:《關於加快新能源汽車推廣應用的指導意見》。《意見》明確,要以純電驅動為新能源汽車發展的主要戰略取向,重點發展純電動汽車、插電式混合動力汽車和燃料電池汽車,以市場主導和政府扶持相結合,建立長期穩定的新能源汽車發展政策體系,創造良好發展環境,加快培育市場,促進新能源汽車產業健康發展。

發改委出臺電動汽車用電價格政策,私家車執行居民電價。為貫徹落實國務院辦公廳《關於加快新能源汽車推廣應用的指導意見》精神,利用價格杠杆促進電動汽車推廣應用,近日,國家發展改革委下發《關於電動汽車用電價格政策有關問題的通知》,確定對電動汽車充換電設施用電實行扶持性電價政策。《通知》的下發,將有利於降低電動汽車使用成本,在鼓勵消費者購買使用電動汽車、促進電動汽車推廣應用方面發揮積極作用。

中國財政部、工信部頒佈新能源汽車免征購置稅。8月6日,財政部、工信部等3部門發佈《關於免征新能源汽車車輛購置稅的公告》,這是自7月份以來,國家相關部門發佈的第四個新能源車政策。上述公告稱,自2014年9月1日至2017年12月31日,對購置的新能源汽車免征車輛購置稅;對免征車輛購置稅的新能源汽車,由工業和資訊化部、國家稅務總局通過發佈《免征車輛購置稅的新能源汽車車型目錄》實施管理。

充電樁基礎設施繼續完善

中國政策引導給力。《政府機關及公共機構購買新能源汽車實施方案》要求政府和公共機關配建相應的充電基礎設施。充電介面與新能源汽車數量比例不低於1:1。同時,北京即將出臺《關於推進物業管理區域新能源小客車自用充電設施安裝的通知》,物業不配合充電樁建設將被罰分。此外,針對新能源車推廣,即將出臺配套檔要求,新建社區停車位配建充電樁的不低於18%,這也將作為規劃審批條件之一。充電樁建設方面,此前上海市發佈了相關辦法,鼓勵社會企業開展充電設施建設和服務,對公共充電設施的投資給予30%的補貼。

國際中德電動汽車充電項目正式啟動。7月8日,默克爾與中國工信部部長苗圩在清華大學共同拉動代表中德電動車合作專案的手柄,中德電動汽車充電項目正式啟動。根據合作協定,未來中國和德國電動車將實現充電介面標準完全統一,雙方還將簽署充電通信協定,最終實現充電設施的完全共用。這意味著未來比亞迪等中國電動車品牌,將與寶馬、奧迪等德國汽車品牌使用相同的充電設施。

中國國網或將退出城市充電設施建設,引入更多社會資本參與建設。繼開放電動汽車充換電設施市場之後,國家電網在充電設施建設領域將再退一步,退出城市中的電動汽車充電設施建設市場,專注於交通幹道上的充電設施建設。多個接近國家電網的人士透露,國家電網的這一決定已經下發各級省級電網公司。決定的主體內容即是:國網將全面退出城市充電設施建領域,引入更多社會資本參與建設,國網則全力推進交通幹道,也即城際互聯充電網路建設。

電池產業鏈蓄勢待發

寶馬欲同賓士等競爭對手共用最新電池技術。寶馬集團日前表示,為了實現規模經濟,對於同競爭對手共用最新電池技術持開放態度。前不久寶馬和三星SDI簽約共同開發電池單元技術,並擴大電池訂單量。

富士康逾20億投資安徽設鋰電池生產線。富士康子公司鋰科科技將在安慶市經開區投資20.9億元,分期建設高分子聚合物電芯及電池組生產專案。富士康還在安徽醞釀其他投資專案,“其中會有新能源汽車方向。”富士康從2005年收購臺灣安泰電業後才正式進入汽車領域,目前主要涉及汽車電子及新能源汽車兩大板塊,分別由安泰電業及鋰科科技兩家公司主導。

松下與特斯拉達成協議,總投資60億建超級電池廠。松下與特斯拉就美國建設電動汽車電池工廠一事達成基本協議。松下的總投資額為1千億日元左右。松下已向特斯拉出資,同時向該公司的電動汽車供應鋰離子電池。電池工廠將在特斯拉主導下建設,將配合需求,分階段擴大產能,松下的初期投資預計為200億~300億日元。松下已將汽車領域定位為成長戰略的支柱,將加快擴大作為環保車核心零部件的電池業務。

三星SDI正與寶馬、大眾、克萊斯勒、福特及印度馬恒達等車企磋商有關電動車電池組供應計畫,也準備參與到中國政府大力推進的新能源車產業。三星SDI在全球電動車專案已達10餘個。同時,繼松下之後,三星SDI從2015年起也將為大眾汽車提供電池。大眾新開發的D-segment中型電動車也將採用三星電池。據瞭解,在2014年初的底特律車展上,大眾就已經採用了三星SDI的電池。三星SDI相關負責人員表示,“寶馬在中國市場快速發展其電動車專案且已初見成效,相信今後電動車電池的供貨量將會高速增長,三星與寶馬的合作也將呈現雙贏局面”。

八家汽車巨頭加盟EPRI 制定和完善電動汽車行業標準。近日八家已經涉足電動汽車領域的巨頭本田,寶馬,克萊斯勒,通用,福特,賓士,三菱和豐田宣佈同其他7家企業共同成立電力科學研究院(EPRI),來制定和完善混合動力和純電動汽車的儀錶、內部結構、充電等相關標準。近日網通社在對將推出的新電池技術進行統計後發現:全新材質電池以及現有鋰離子電池的改進,正成為電動汽車發展的趨勢,未來隨著新電池技術的推出,電動車續航里程有望達到特斯拉四倍,達到1600公里之多。

車企近來動作頻頻

寶馬集團發佈未來戰略佈局中國市場。日前,寶馬集團在其新聞發佈會上確認,寶馬集團與華晨中國汽車控股有限公司(以下簡稱“華晨汽車”)的合資協議延長至2028年;基於這一合作基礎,寶馬集團公佈了接下來在中國市場的一系列戰略佈局,包括擴大在華產能、拓展國產產品線,以及在中國投產先進的發動機等,展示了寶馬集團對中國市場更加強勁的投入。寶馬集團對於中國市場寄予厚望,認為中國有望成為世界上最大的新能源汽車市場。目前,寶馬集團和華晨寶馬可以提供的電動汽車解決方案包括BMW i系列、採用新能源動力的BMW車型,以及之諾品牌產品,以期在中國“綠色交通”發展過程中搶佔先機。

比亞迪牽手廣汽成立新能源客車公司。8月4日晚間,比亞迪和廣汽集團同時發佈公告稱,二者將成立合資公司生產新能源客車,雙方聯手佈局新能源汽車市場。據業內分析,比亞迪攜手廣汽集團將有助於發揮二者在汽車製造銷售方面的優勢。廣汽集團固有的汽車製造能力及銷售管道將為比亞迪目前上市的新能源車型拓展銷路。比亞迪整車製造能力方面的缺陷也可借力廣汽集團彌補,公司可以專攻擴大電池產能。

陳虹醞釀前瞻技術部,上汽研發資源向新能源傾斜。上汽集團董事長陳虹要對上汽研發體系進行整合,醞釀推出前瞻性技術部,未來每年都會投入3億用於前瞻科技研究,主要涉及新能源、輕量化及車聯網三大領域。

上汽集團宣佈要與阿裡巴巴聯合造新能源車。據悉,上汽和阿裡的“互聯網汽車”從源頭上重新定義汽車和車載系統。其目標是使使用者通過汽車與網路無縫對接,徹底改變當前車載系統功能簡單、使用者體驗不佳的種種局限。

樂視與北汽或將打造“樂視電動汽車”。北汽董事長徐和誼也在密會樂視CEO賈躍亭,並向外界釋放信號表示願意“代工生產樂視汽車”。而近日。搜狐前副總編、汽車事業部總經理何毅從搜狐離職加盟樂視,未來或負責組建汽車團隊。北汽對於新能源車的發展信心滿滿,稱2年內將打造“中國的特斯拉”。

目前國內新能源汽車在售車型接近20款,預計未來兩年還將投放接近30款新車,投放速度明顯加快。隨著產品投放加快,各車企對於新能源汽車產能的準備,尤其是電池等產業鏈的配套能力進行了充分準備,特斯拉完成消費者教育,消費者開始考慮購買新能源汽車,分時租賃等新商業模式引進,進一步促進新能源銷量提升。新能源政策的不斷落地,及特斯拉的鯰魚攪動效應,無論是中國資本市場還是實體企業,都掀起了一股新能源汽車熱。

在此背景下,將於11月12日-14日在中國北京召開。大會由中國汽車工業協會和決策者會議聯合主辦,交通大學汽車工程研究院協辦,得到日本汽車工業協會和眾多一線整車商鼎力支持。主題為新增長局勢下的中國新能源汽車產業動態聚焦,專注於新能源整車商項目、戰略規劃以及對核心設備的需求、對於新能源汽車電氣以及動力系統、電控系統、智慧汽車創新、動力電池沖換電基建建設系統的案例分析以及核心技術的全面探討。作為中國電動汽車行業領先的峰會,新能源汽車峰會歷經4年發展,無論是參會企業,還是贊助商數量都位居國內前列。歡迎政府機關行業協會、海內外汽車生產商、科研單位、大學院校、汽車電池生產商、核心零部件提供商、整體服務解決方案提供商及其他服務提供者來電諮詢。

【本屆參數統計】

600+業內權威專家業內專業人士,400+專業參展觀眾,來自于320+行業知名企業單位,23+個國家
120+位參會代表來自語全球領先整車商,以及110+核心零部件提供商企業代表
40+ 知名權威發言人,為您敘說新能源汽車行業熱點資訊
16+ 小時商務交流機會,貫穿於雞尾酒會,小組討論,交流午宴及提問互動環節
6 場專題討論,為您深度解析關注行業熱點
5 年歷史,鑄就行業年度盛會

【展會特色】

實效性:展會期間將進行一對一會談、頒獎典禮,突出實效和品牌,做大做深供求雙方專業化配對洽談工作,為廣大業內人士及下游應用企業提供集中領略行業最新趨勢的機會。
品牌化:作為中國電動汽車行業最早商業化運作的峰會,歷經四年發展,無論是參會數量,還是贊助商數量,在國內同行業峰會中,都是雄踞前列,深受業界同仁的認可和讚揚,其知名度和美譽度在業內廣為流傳。成為中國電動汽車行業名符其實的第一會。 
國際化:往屆嘉賓有來自美國、日本、韓國、德國、丹麥、義大利、臺灣等國家和地區的國際企業參會,已經成為電動汽車行業的資訊分享、技術交流、貿易採購平臺。
專業化:是國內目前唯一的電動汽車行業的專業峰會之一,一年一屆。內容包含電動汽車(含混合動力)的整車、零部件、管理系統、充電站及相關配套設施等. 將吸引來自中國電動汽車企業超320家企業巨頭高層參觀,雲集政府機關行業協會,整車商,大學院校及研究院,零部件百強企業,核心技術設備提供商。
全媒體曝光:主辦方將基於網站、雜誌、微信、微博等多媒體平臺,在展前、展中、展後分別做全方位即時報導,預計將會實現超過10萬人次覆蓋。

【2014年新能源汽車頒獎典禮獎項設置】

年度優秀電動汽車電池生廠商獎
年度優秀新能源汽車諮詢公司獎
年度優秀新能源汽車解決方案提供商獎
終身成就獎
企業社會責任商獎
優秀核心零部件提供商獎
優秀新能源汽車服務商獎
優秀新能源汽車技術提供商獎

【展商評價】

“是一個尋找合作夥伴的理想場所,本次參展讓我們受益頗多,明年會一如既往支援綠色汽車大會!”—— Shinry Technologies Co., Ltd
“通過很好的管道將我們的產品展現在客戶面前,非常滿意。”—— AGC Automtive
“綠色汽車大會提供一個行業人士交流的平臺,參會參展企業眾多,達到了我們的參展期望值。”—— Thermal Hazard Technology
“我們同時參加了峰會和展覽,非常值得推薦的活動!”—— 捷特科
“非常滿意,無論是活動內容,參會嘉賓,還是規模層次都很出色,會推薦個同事。”—— W.E.T. Automotive Systems (China) Ltd

  展會網站:  

連絡人: 邱小姐(Elva Qiu)

電話 : +86 21 63931899-2041

手機:+86 18930215786

郵箱:

QQ:1147789586

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

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

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

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

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

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

※回頭車貨運收費標準

排氣不符規定 德要求戴姆勒召回數十萬輛柴油車

摘錄自2019年10月12日中央通訊社德國報導

德國汽車製造商戴姆勒(Daimler)12日表示,聯邦交通管理局(KBA)以違反排氣規定為由,要求召回數十萬輛柴油車。戴姆勒說,這波召回的數量估計將達6位數,並表示會「與有關當局合作」。

公司在聲明中表示,這次的召回涉及至少26萬輛Sprinter廂型車,並表示所有車輛都在2016年6月之前生產。

德國福斯汽車(Volkswagen)2015年承認在全球1100萬輛柴油車上安裝非法「減效裝置」(defeat device),包括歐洲850萬輛及美國60萬輛車,德國有關當局隨後展開這起造假醜聞「柴油門」調查。自從「柴油門」4年前爆發,這場排放造假醜聞就對汽車產業造成巨大後果。部分汽車排放與呼吸道及心血管疾病有關的有害氮氧化物,高達法律規定數值的40倍。

據德國媒體報導,聯邦交通管理局本月稍早展開調查,懷疑戴姆勒安裝「非法軟體」,試圖讓車輛在實驗室測試時的排汙量看起來比實際低。戴姆勒早已召回約70萬輛車,包括德國境內就有近30萬輛車被召回。

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

【其他文章推薦】

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

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

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

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

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

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

技術乾貨丨卷積神經網絡之LeNet-5遷移實踐案例

摘要:LeNet-5是Yann LeCun在1998年設計的用於手寫数字識別的卷積神經網絡,當年美國大多數銀行就是用它來識別支票上面的手寫数字的,它是早期卷積神經網絡中最有代表性的實驗系統之一。可以說,LeNet-5就相當於編程語言入門中的“Hello world!”。

華為的昇騰訓練芯片一直是大家所期待的,目前已經開始提供公測,如何在昇騰訓練芯片上運行一個訓練任務,這是目前很多人都在采坑過程中,所以我寫了一篇指導文章,附帶上所有相關源代碼。注意,本文並沒有包含環境的安裝,請查看另外相關文檔。

環境約束:昇騰910目前僅配套TensorFlow 1.15版本。

基礎鏡像上傳之後,我們需要啟動鏡像命令,以下命令掛載了8塊卡(單機所有卡):

docker run -it –net=host –device=/dev/davinci0 –device=/dev/davinci1 –device=/dev/davinci2 –device=/dev/davinci3 –device=/dev/davinci4 –device=/dev/davinci5 –device=/dev/davinci6 –device=/dev/davinci7 –device=/dev/davinci_manager –device=/dev/devmm_svm –device=/dev/hisi_hdc -v /var/log/npu/slog/container/docker:/var/log/npu/slog -v /var/log/npu/conf/slog/slog.conf:/var/log/npu/conf/slog/slog.conf -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ -v /usr/local/Ascend/driver/tools/:/usr/local/Ascend/driver/tools/ -v /data/:/data/ -v /home/code:/home/local/code -v ~/context:/cache ubuntu_18.04-docker.arm64v8:v2 /bin/bash

設置環境變量並啟動手寫字訓練網絡:

#!/bin/bash
export LD_LIBRARY_PATH=/usr/local/lib/:/usr/local/HiAI/runtime/lib64
export PATH=/usr/local/HiAI/runtime/ccec_compiler/bin:$PATH
export CUSTOM_OP_LIB_PATH=/usr/local/HiAI/runtime/ops/framework/built-in/tensorflow
export DDK_VERSION_PATH=/usr/local/HiAI/runtime/ddk_info
export WHICH_OP=GEOP
export NEW_GE_FE_ID=1
export GE_AICPU_FLAG=1
export OPTION_EXEC_EXTERN_PLUGIN_PATH=/usr/local/HiAI/runtime/lib64/plugin/opskernel/libfe.so:/usr/local/HiAI/runtime/lib64/plugin/opskernel/libaicpu_plugin.so:/usr/local/HiAI/runtime/lib64/plugin/opskernel/libge_local_engine.so:/usr/local/H
iAI/runtime/lib64/plugin/opskernel/librts_engine.so:/usr/local/HiAI/runtime/lib64/libhccl.so
 
export OP_PROTOLIB_PATH=/usr/local/HiAI/runtime/ops/built-in/
 
export DEVICE_ID=2
export PRINT_MODEL=1
#export DUMP_GE_GRAPH=2
 
#export DISABLE_REUSE_MEMORY=1
#export DUMP_OP=1
#export SLOG_PRINT_TO_STDOUT=1
 
export RANK_ID=0
export RANK_SIZE=1
export JOB_ID=10087
export OPTION_PROTO_LIB_PATH=/usr/local/HiAI/runtime/ops/op_proto/built-in/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/Ascend/fwkacllib/lib64/:/usr/local/Ascend/driver/lib64/common/:/usr/local/Ascend/driver/lib64/driver/:/usr/local/Ascend/add-ons/
export PYTHONPATH=$PYTHONPATH:/usr/local/Ascend/opp/op_impl/built-in/ai_core/tbe
export PATH=$PATH:/usr/local/Ascend/fwkacllib/ccec_compiler/bin
export ASCEND_HOME=/usr/local/Ascend
export ASCEND_OPP_PATH=/usr/local/Ascend/opp
export SOC_VERSION=Ascend910
 
rm -f *.pbtxt
rm -f *.txt
rm -r /var/log/npu/slog/*.log
rm -rf train_url/*
 
 
python3 mnist_train.py

以下訓練案例中我使用的lecun大師的LeNet-5網絡,先簡單介紹LeNet-5網絡:

LeNet5誕生於1994年,是最早的卷積神經網絡之一,並且推動了深度學習領域的發展。自從1988年開始,在多年的研究和許多次成功的迭代后,這項由Yann LeCun完成的開拓性成果被命名為LeNet5。

LeNet-5包含七層,不包括輸入,每一層都包含可訓練參數(權重),當時使用的輸入數據是32*32像素的圖像。下面逐層介紹LeNet-5的結構,並且,卷積層將用Cx表示,子採樣層則被標記為Sx,完全連接層被標記為Fx,其中x是層索引。

層C1是具有六個5*5的卷積核的卷積層(convolution),特徵映射的大小為28*28,這樣可以防止輸入圖像的信息掉出卷積核邊界。C1包含156個可訓練參數和122304個連接。

層S2是輸出6個大小為14*14的特徵圖的子採樣層(subsampling/pooling)。每個特徵地圖中的每個單元連接到C1中的對應特徵地圖中的2*2個鄰域。S2中單位的四個輸入相加,然後乘以可訓練係數(權重),然後加到可訓練偏差(bias)。結果通過S形函數傳遞。由於2*2個感受域不重疊,因此S2中的特徵圖只有C1中的特徵圖的一半行數和列數。S2層有12個可訓練參數和5880個連接。

層C3是具有16個5-5的卷積核的卷積層。前六個C3特徵圖的輸入是S2中的三個特徵圖的每個連續子集,接下來的六個特徵圖的輸入則來自四個連續子集的輸入,接下來的三個特徵圖的輸入來自不連續的四個子集。最後,最後一個特徵圖的輸入來自S2所有特徵圖。C3層有1516個可訓練參數和156 000個連接。

層S4是與S2類似,大小為2*2,輸出為16個5*5的特徵圖。S4層有32個可訓練參數和2000個連接。

層C5是具有120個大小為5*5的卷積核的卷積層。每個單元連接到S4的所有16個特徵圖上的5*5鄰域。這裏,因為S4的特徵圖大小也是5*5,所以C5的輸出大小是1*1。因此S4和C5之間是完全連接的。C5被標記為卷積層,而不是完全連接的層,是因為如果LeNet-5輸入變得更大而其結構保持不變,則其輸出大小會大於1*1,即不是完全連接的層了。C5層有48120個可訓練連接。

F6層完全連接到C5,輸出84張特徵圖。它有10164個可訓練參數。這裏84與輸出層的設計有關。

LeNet的設計較為簡單,因此其處理複雜數據的能力有限;此外,在近年來的研究中許多學者已經發現全連接層的計算代價過大,而使用全部由卷積層組成的神經網絡。

LeNet-5網絡訓練腳本是mnist_train.py,具體代碼:

import os
import numpy as np
import tensorflow as tf
import time
from tensorflow.examples.tutorials.mnist import input_data
 
import mnist_inference
 
from npu_bridge.estimator import npu_ops #導入NPU算子庫
from tensorflow.core.protobuf.rewriter_config_pb2 import RewriterConfig #重寫tensorFlow里的配置,針對NPU的配置
 
 
batch_size = 100
learning_rate = 0.1
training_step = 10000
 
model_save_path = "./model/"
model_name = "model.ckpt"
 
def train(mnist):
    x = tf.placeholder(tf.float32, [batch_size, mnist_inference.image_size, mnist_inference.image_size, mnist_inference.num_channels], name = 'x-input')
    y_ = tf.placeholder(tf.float32, [batch_size, mnist_inference.num_labels], name = "y-input")
 
    regularizer = tf.contrib.layers.l2_regularizer(0.001)
    y = mnist_inference.inference(x, train = True, regularizer = regularizer) #推理過程
    global_step = tf.Variable(0, trainable=False)
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = y, labels = tf.argmax(y_, 1)) #損失函數
    cross_entropy_mean = tf.reduce_mean(cross_entropy)
    loss = cross_entropy_mean + tf.add_n(tf.get_collection("loss"))
 
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step = global_step) #優化器調用
 
    saver = tf.train.Saver() #啟動訓練
 
#以下代碼是NPU所必須的代碼,開始配置參數
    config = tf.ConfigProto(
        allow_soft_placement = True,
        log_device_placement = False)
    custom_op =  config.graph_options.rewrite_options.custom_optimizers.add()
    custom_op.name =  "NpuOptimizer"
    custom_op.parameter_map["use_off_line"].b = True
    #custom_op.parameter_map["profiling_mode"].b = True
    #custom_op.parameter_map["profiling_options"].s = tf.compat.as_bytes("task_trace:training_trace")
config.graph_options.rewrite_options.remapping = RewriterConfig.OFF
#配置參數結束
 
    writer = tf.summary.FileWriter("./log_dir", tf.get_default_graph())
    writer.close()
 
 
#參數初始化
    with tf.Session(config = config) as sess:
        tf.global_variables_initializer().run()
 
        start_time = time.time()
 
        for i in range(training_step):
xs, ys = mnist.train.next_batch(batch_size)
            reshaped_xs = np.reshape(xs, (batch_size, mnist_inference.image_size, mnist_inference.image_size, mnist_inference.num_channels))
            _, loss_value, step = sess.run([train_step, loss, global_step], feed_dict={x:reshaped_xs, y_:ys})
 
            #每訓練10個epoch打印損失函數輸出日誌
            if i % 10 == 0:
                print("****************************++++++++++++++++++++++++++++++++*************************************\n" * 10)
                print("After %d training steps, loss on training batch is %g, total time in this 1000 steps is %s." % (step, loss_value, time.time() - start_time))
                #saver.save(sess, os.path.join(model_save_path, model_name), global_step = global_step)
                print("****************************++++++++++++++++++++++++++++++++*************************************\n" * 10)
                start_time = time.time()
def main():
    mnist = input_data.read_data_sets('MNIST_DATA/', one_hot= True)
    train(mnist)
 
if __name__ == "__main__":
    main()

本文主要講述了經典卷積神經網絡之LeNet-5網絡模型和遷移至昇騰D910的實現,希望大家快來動手操作一下試試看!

 

點擊關注,第一時間了解華為雲新鮮技術~

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

新來的”大神”用策略模式把if else給”優化”了,技術總監說:能不能想好了再改?

本文來自作者投稿,原作者:上帝愛吃蘋果

目前在魔都,貝殼找房是我的僱主,平時關注一些 java 領域相關的技術,希望你們能在這篇文章中找到些有用的東西。個人水平有限,如果文章有錯誤還請指出,在留言區一起交流。

我想大家肯定都或多或少的看過各種“策略模式”的講解、佈道等等,這篇文章就是來好好“澄清”一下策略模式,並嘗試回答以下的問題:

1. 策略模式是如何優化業務邏輯代碼結構的?

2. 殺雞焉用宰牛刀?就是幾個if else場景我需要用到策略模式?

3. 有沒有什麼更好的代碼結構來實現策略模式的嗎?

策略模式是如何優化業務邏輯代碼結構的?

要回答這個問題,我們還得先扒一扒策略模式的定義,從定義着手來理解它

策略模式的教科書定義

它的定義很精簡:一個類的行為或其算法可以在運行時更改。我們把它降維到代碼層面,用人話翻譯一下就是,運行時我給你這個類的方法傳不同的“key”,你這個方法會執行不同的業務邏輯。細品一下,這不就是 if else 乾的事嗎?

策略模式優化了什麼?

其實策略模式的核心思想和 if else如出一轍,根據不同的key動態的找到不同的業務邏輯,那它就只是如此嗎?

實際上,我們口中的策略模式其實就是在代碼結構上調整,用接口+實現類+分派邏輯來使代碼結構可維護性好點。

一般教科書上講解到接口與實現類就結束了,其他博客上會帶上提及分派邏輯。這裏就不啰嗦了。

小結一下,即使用了策略模式,你該寫的業務邏輯照常寫,到邏輯分派的時候,還是變相的if else。而它的優化點是抽象了出了接口,將業務邏輯封裝成一個一個的實現類,任意地替換。在複雜場景(業務邏輯較多)時比直接 if else 來的好維護些。

殺雞焉用宰牛刀?就是幾個if else場景我需要用到策略模式?!

我想小夥伴們經常有這樣的不滿,我的業務邏輯就3 4 行,你給我整一大堆類定義?有必要這麼麻煩嗎?我看具體的業務邏輯還需要去不同的類中,簡單點行不行。

其實我們所不滿的就是策略模式帶來的缺點:

1、策略類會增多

2、業務邏輯分散到各個實現類中,而且沒有一個地方可以俯視整個業務邏輯

針對傳統策略模式的缺點,在這分享一個實現思路,這個思路已經幫我們團隊解決了多個複雜if else的業務場景,理解上比較容易,代碼上需要用到Java8的特性——利用Map與函數式接口來實現。

直接show代碼結構:為了簡單演示一個思路,代碼用String 類型來模擬一個業務BO

其中:

  1. getCheckResult() 為傳統的做法

  2. getCheckResultSuper()則事先在Map中定義好了“判斷條件”與“業務邏輯”的映射關係,具體講解請看代碼註釋

/**
 * 某個業務服務類
 */
@Service
public class BizService {

    /**
     * 傳統的 if else 解決方法
     * 當每個業務邏輯有 3 4 行時,用傳統的策略模式不值得,直接的if else又顯得不易讀
     */
    public String getCheckResult(String order) {
        if ("校驗1".equals(order)) {
            return "執行業務邏輯1";
        } else if ("校驗2".equals(order)) {
            return "執行業務邏輯2";
        }else if ("校驗3".equals(order)) {
            return "執行業務邏輯3";
        }else if ("校驗4".equals(order)) {
            return "執行業務邏輯4";
        }else if ("校驗5".equals(order)) {
            return "執行業務邏輯5";
        }else if ("校驗6".equals(order)) {
            return "執行業務邏輯6";
        }else if ("校驗7".equals(order)) {
            return "執行業務邏輯7";
        }else if ("校驗8".equals(order)) {
            return "執行業務邏輯8";
        }else if ("校驗9".equals(order)) {
            return "執行業務邏輯9";
        }
        return "不在處理的邏輯中返回業務錯誤";
    }

    /**
     * 業務邏輯分派Map
     * Function為函數式接口,下面代碼中 Function<String, String> 的含義是接收一個Stirng類型的變量,返回一個String類型的結果
     */
    private Map<String, Function<String, String>> checkResultDispatcher = new HashMap<>();

    /**
     * 初始化 業務邏輯分派Map 其中value 存放的是 lambda表達式
     */
    @PostConstruct
    public void checkResultDispatcherInit() {
        checkResultDispatcher.put("校驗1", order -> String.format("對%s執行業務邏輯1", order));
        checkResultDispatcher.put("校驗2", order -> String.format("對%s執行業務邏輯2", order));
        checkResultDispatcher.put("校驗3", order -> String.format("對%s執行業務邏輯3", order));
        checkResultDispatcher.put("校驗4", order -> String.format("對%s執行業務邏輯4", order));
        checkResultDispatcher.put("校驗5", order -> String.format("對%s執行業務邏輯5", order));
        checkResultDispatcher.put("校驗6", order -> String.format("對%s執行業務邏輯6", order));
        checkResultDispatcher.put("校驗7", order -> String.format("對%s執行業務邏輯7", order));
        checkResultDispatcher.put("校驗8", order -> String.format("對%s執行業務邏輯8", order));
        checkResultDispatcher.put("校驗9", order -> String.format("對%s執行業務邏輯9", order));
    }

    public String getCheckResultSuper(String order) {
        //從邏輯分派Dispatcher中獲得業務邏輯代碼,result變量是一段lambda表達式
        Function<String, String> result = checkResultDispatcher.get(order);
        if (result != null) {
            //執行這段表達式獲得String類型的結果
            return result.apply(order);
        }
        return "不在處理的邏輯中返回業務錯誤";
    }
}

通過http調用一下看看效果:

/**
 * 模擬一次http調用
 */
@RestController
public class BizController {

    @Autowired
    private BizService bizService;

    @PostMapping("/v1/biz/testSuper")
    public String test2(String order) {
        return bizService.getCheckResultSuper(order);
    }
}

這是個簡單的demo演示,之後會舉一些複雜的場景案例。

魯迅曾說過,“每解決一個問題,就會因出更多的問題”。我們一起來看看這樣的實現有什麼好處,會帶來什麼問題。

好處很直觀:

  1. 在一段代碼里直觀的看到”判斷條件”與業務邏輯的映射關係
  2. 不需要單獨定義接口與實現類,直接使用現有的函數式接口(什麼?不知道函數式接口?快去了解),而實現類直接就是業務代碼本身。

不好的點:

  1. 需要團隊成員對lambda表達式有所了解(什麼?Java14都出來了還有沒用上Java8新特性的小夥伴?)

接下來我舉幾個在業務中經常遇到的if else場景,並用Map+函數式接口的方式來解決它

在真實業務場景問題的解決思路

有的小夥伴會說,我的判斷條件有多個啊,而且很複雜,你之前舉個例子只有單個判斷邏輯,而我有多個判斷邏輯該怎麼辦呢?

很好解決:寫一個判斷邏輯的方法,Map的key由方法計算出

/**
 * 某個業務服務類
 */
@Service
public class BizService {

    private Map<String, Function<String, String>> checkResultDispatcherMuti = new HashMap<>();

    /**
     * 初始化 業務邏輯分派Map 其中value 存放的是 lambda表達式
     */
    @PostConstruct
    public void checkResultDispatcherMuitInit() {
        checkResultDispatcherMuti.put("key_訂單1", order -> String.format("對%s執行業務邏輯1", order));
        checkResultDispatcherMuti.put("key_訂單1_訂單2", order -> String.format("對%s執行業務邏輯2", order));
        checkResultDispatcherMuti.put("key_訂單1_訂單2_訂單3", order -> String.format("對%s執行業務邏輯3", order));
    }

    public String getCheckResultMuti(String order, int level) {
        //寫一段生成key的邏輯:
        String ley = getDispatcherKey(order, level);

        Function<String, String> result = checkResultDispatcherMuti.get(ley);
        if (result != null) {
            //執行這段表達式獲得String類型的結果
            return result.apply(order);
        }
        return "不在處理的邏輯中返回業務錯誤";
    }

    /**
     * 判斷條件方法
     */
    private String getDispatcherKey(String order, int level) {
        StringBuilder key = new StringBuilder("key");
        for (int i = 1; i <= level; i++) {
            key.append("_" + order + i);
        }
        return key.toString();
    }
}

用http模擬一下:

/**
 * 模擬一次http調用
 */
@RestController
public class BizController {

    @Autowired
    private BizService bizService;

    @PostMapping("/v1/biz/testMuti")
    public String test1(String order, Integer level) {
        return bizService.getCheckResultMuti(order, level);
    }
}

只要設計好你的key的生成規則就好。

還有小夥伴會問:我的業務邏輯有很多很多行,在checkResultDispatcherMuitInit()方法的Map中直接寫不會很長嗎?

直接寫當然長了,我們可以抽象出一個service服務專門放業務邏輯,然後在定義中調用它就好了:

提供一個業務邏輯單元:

/**
 * 提供業務邏輯單元
 */
@Service
public class BizUnitService {

    public String bizOne(String order) {
        return order + "各種花式操作1";
    }
    public String bizTwo(String order) {
        return order + "各種花式操作2";
    }
    public String bizThree(String order) {
        return order + "各種花式操作3";
    }
}
/**
 * 某個業務服務類
 */
@Service
public class BizService {
    @Autowired
    private BizUnitService bizUnitService;

    private Map<String, Function<String, String>> checkResultDispatcherComX = new HashMap<>();

    /**
     * 初始化 業務邏輯分派Map 其中value 存放的是 lambda表達式
     */
    @PostConstruct
    public void checkResultDispatcherComXInit() {
        checkResultDispatcherComX.put("key_訂單1", order -> bizUnitService.bizOne(order));
        checkResultDispatcherComX.put("key_訂單1_訂單2", order -> bizUnitService.bizTwo(order));
        checkResultDispatcherComX.put("key_訂單1_訂單2_訂單3", order -> bizUnitService.bizThree(order));
    }

    public String getCheckResultComX(String order, int level) {
        //寫一段生成key的邏輯:
        String ley = getDispatcherComXKey(order, level);

        Function<String, String> result = checkResultDispatcherComX.get(ley);
        if (result != null) {
            //執行這段表達式獲得String類型的結果
            return result.apply(order);
        }
        return "不在處理的邏輯中返回業務錯誤";
    }

    /**
     * 判斷條件方法
     */
    private String getDispatcherComXKey(String order, int level) {
        StringBuilder key = new StringBuilder("key");
        for (int i = 1; i <= level; i++) {
            key.append("_" + order + i);
        }
        return key.toString();
    }
}

調用結果:

總結

最後,我們一起嘗試回答以下幾個問題:

1. 策略模式是如何優化業務邏輯代碼結構的?

抽象了出了接口,將業務邏輯封裝成一個一個的實現類,任意地替換。在複雜場景(業務邏輯較多)時比直接 if else 來的好維護些。

2. 殺雞焉用宰牛刀?就是幾個if else場景我需要用到策略模式?!

我們所不滿的其實就是傳統接口實現的缺點: 1、策略類會很多。 2、業務邏輯分散到各個實現類中,而且沒有一個地方可以俯覽整個業務邏輯

3. 有沒有什麼更好的代碼結構來實現策略模式的嗎?

針對傳統策略模式的缺點,分享了利用Map與函數式接口來實現的思路。

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

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

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

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

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

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

※回頭車貨運收費標準

抗議氣候變遷 奧斯卡影后珍芳達被捕

摘錄自2019年10月12日中央通訊社美國報導

奧斯卡影后珍芳達(Jane Fonda)12日在美國國會山莊外被逮捕,當時她參與氣候變遷抗議活動,並在現場發表談話要求當局採取行動保護環境,之後就被警方銬上手銬帶走。

法新社報導,長期投身社會運動的珍芳達在臉書(Facebook)專頁張貼的影片顯示,她在國會大廈的階梯上抗議長達10分鐘後,便與其他數名人士一同遭到拘押。

警方發言人發布聲明說:「美國國會警察局(US Capitol Police)今天逮捕16人,因為他們違法在國會山莊東側抗議。」但聲明並未指明是哪些人被捕。

81歲的珍芳達穿著亮紅色大衣,反覆呼喊氣候變遷相關口號,而後她被警方銬上手銬,並在其他示威者的歡呼聲下被帶走。數個小時後珍芳達就被釋放。

珍芳達近期告訴「洛杉磯時報」(Los Angeles Times),她將搬到華府4個月,並效法瑞典環保少女桑柏格(Greta Thunberg)的熱情,全心全力對抗全球暖化。

珍芳達被捕前曾向現場一小群人發表談話,她痛斥氣候變遷這項「人為危機」,還說自己跟其他環保人士「每週五中午11時,無論晴天、雨天、下雪或暴風雪」,他們都會回到國會山莊展開一連串示威活動。

「紐約時報」(New York Times)報導,珍芳達若因參與違法示威活動被定罪,將面臨最多250美元(約新台幣7660元)罰款,以及最高90天的刑期。

珍芳達曾分別以1971年「柳巷芳草」(Klute)與1978年「歸返家園」(Coming Home)兩部作品,摘下奧斯卡影后殊榮。

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

【其他文章推薦】

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

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

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

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

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

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

基於層級表達的高效網絡搜索方法 | ICLR 2018

論文基於層級表達提出高效的進化算法來進行神經網絡結構搜索,通過層層堆疊來構建強大的卷積結構。論文的搜索方法簡單,從實驗結果看來,達到很不錯的準確率,值得學習

來源:【曉飛的算法工程筆記】 公眾號

論文: Hierarchical Representations for Efficient Architecture Search

  • 論文地址:https://arxiv.org/abs/1711.00436

Introduction

  由於網絡的驗證需要耗費很長的時間,神經網絡結構搜索計算量非常巨大,很多研究通過降低搜索空間的複雜度來提高搜索的效率。論文通過加入分層網絡結構來約束搜索空間,在最初幾層僅使用卷積和池化等簡單操作,逐步到高層將底層的block進行組合搭建,最後將最高層的block堆疊成最終的網絡。由於搜索空間設計夠好,網絡的搜索方法僅用進化算法或隨機搜索足以。
  論文總結如下:

  • 提出對神經網絡結構的層級表達
  • 通過實驗證明搜索空間的設計十分重要,可以降低搜索方法的投入,甚至隨機搜索也可以
  • 提出可擴展的進化搜索方法,對比其它進化搜索方法有更好的結果

Architecture Representations

Flat Architecture Representation

  將神經網絡結構定義為單輸入、單輸出的計算圖,圖中每個節點代表特徵圖,每條有向邊為基本操作(卷積、池化等),所以網絡的表達$(G,o)$包含兩部分:

  1. 一個有效的操作集合$o={o_1,o_2,…}$
  2. 一個鄰接矩陣$G$,用以指定操作的神經網絡圖,$G_{ij}=k$為節點$i$和節點$j$間的操作為$o_k$

  將操作集$o$和鄰接矩陣$G$組合起來就得到網絡的結構

  每個節點$i$的特徵圖$x_i$由其前面的節點$j$通過公式2計算而得,$|G|$是圖中節點數量,$merge$將多個特徵圖合併成一個的操作,這裏直接使用depthwise concatentation,由於element-wise addition要求維度一致,比較不靈活,而且如果融合特徵後接的是$1\times 1$卷積,這就其實類似於做concatienation

Hierarchical Architecture Representation

  層級結構表達的關鍵是找到不同的層級的模版,在構建高層模版時使用低層的模版作為積木(operation)進行構建

  對於$L$層的層級關係,$\ell$層包含$M_{\ell}$個模版,最高層$\ell=L$僅包含一個模版,對應完整的網絡,最低層$\ell=1$是元操作集,定義$o_m{(\ell)}$為$\ell$層的第$m$個模版,為低層模版$o{(\ell)}={o_1^{(\ell -1)},o_2^{(\ell -1)},…,o_1^{(\ell – 1)}}$根據公式3的組合。最終的層級結構表達為$({{G_m{(\ell)}}_{m=1}M}_{\ell=2}L,o{(1)})$,由每層的模版的網絡結構關係和最底層操作定義,如圖1

Primitive Operations

  低層的原操作共六種($\ell=1$,$M_t=6$):

  • 1 × 1 convolution of C channels
  • 3 × 3 depthwise convolution
  • 3 × 3 separable convolution of C channels
  • 3 × 3 max-pooling
  • 3 × 3 average-pooling
  • identity

  使用時,所有元操作為stride=1,以及進行padded來保留分辨率,卷積后都接BN+ReLU,維度固定為$C$。另外每層都有$none$操作,代表節點$i$和節點$j$之間沒有連接

Evolutionary Architecture Search

Mutation

  分層基因的變異包含以下步驟:

  • 採樣一個非原始層$\ell\ge2$作為目標層
  • 在目標層採樣一個模版$m$作為目標模版
  • 在目標模版中採樣一個後繼節點$i$
  • 在目標模版中採樣一個前置節點$j$
  • 隨機替換當前操作$o_k^{(\ell -1)}$為其它操作$o_{k{‘}}{(\ell -1)}$

  對於當前層級只有兩層的,第一步直接將$\ell$設為2,變異可總結為公式4,$\ell$,$m$,$i$,$j$,$k^{‘}$從各自區域的均勻分佈中隨機抽樣得到,上面的突變足夠對模版產生3種修改:

  • 添加邊:$o_k^{(\ell -1)}=none$,$o_{k{‘}}{(\ell -1)}\ne none$
  • 修改存在的邊:$o_k^{(\ell -1)}\ne none$,$o_{k{‘}}{(\ell -1)}\ne none$,$o_k^{(\ell -1)}\ne o_{k{‘}}{(\ell -1)}$
  • 刪除存在的邊:$o_k^{(\ell -1)}\ne none$,$o_{k{‘}}{(\ell -1)}= none$

Initialization

  基因指代完整的網絡,基因的種群初始化包含兩個步驟:

  1. 建立一個不重要的基因,每個模版都使用identity進行連接
  2. 對基因進行大批量的隨機變異來多樣化

  對比以前的研究使用常見的網絡進行基因初始化,這樣的初始化不僅能很好地覆蓋不常見的網絡的搜索空間,還能去除人工初始化帶來的傳統偏向

Search Algorithms

  論文的進化算法基於錦標賽選擇(tournament selection),首先對初始化的種群網絡進行訓練和測試得到分數,然後從種群中隨機獲取5%的基因,表現最好的基因進行突變得到新網絡,在訓練和測試後放入種群中,重複進行上述選取與放回,種群數量不斷增大,最終取種群表現最好的基因
  論文也使用隨機搜索進行實驗,基因種群隨機生成,然後進行訓練和驗證,選取最好的模型,這種方法的主要好處在於能整個種群并行化計算,減少搜索時間

Implementation

  論文使用異步分佈式進行實現,包含一個controller和多個worker,分別負責基因的進化和測試,兩者共享一個內存表格$\mathcal{M}$,記錄基因及其準確率(fitness),還有一個數據隊列$\mathcal{Q}$,包含待測試的基因

  當有worker空餘時,controller使用錦標賽選擇從$\mathcal{M}$中選擇一個基因進行突變,然後放到隊列$\mathcal{Q}$中等待測試

  worker從$\mathcal{Q}$中拿到待測試的基因,測試後放到$\mathcal{M}$中,訓練是從頭開始訓練的,沒有使用權值共享加速

Experiments and Results

Experimental Setup

  在實驗中,沒有對整體網絡進行搜索,而是使用提出的方法進行卷積單元(cell)的搜索,這樣能夠在小網絡上快速進行網絡測試然後遷移到較大的網絡。具體的各結構如圖2,每個cell後面接$2c$維度和$stride=2$的$3\times 3$分離卷積,用於升維和降低分辨率,最後一個cell後面接$c$維度和$stride=1$的$3\times 3$分離卷積

Architecture Search on CIFAR-10

  200卡,初始種群為200,層級$L=3$,每層模版的操作分別為$M_1=6$,$M_2=6$和$M_3=1$,每層($\ell \ge2$)的節點圖分別為$|G{(2)}|=4$和$|G{(3)}|=5$,層2的模版跟一個跟模版輸入維度一樣$1\times 1$的卷積來降維。對於用於對比的不分層的搜索方法,則使用11個節點的計算圖。從圖3來看,論文提出的方法在收斂速度、準確率和參數量上都不錯

  為了進一步展示論文方法的效果,對圖3中間的結果的每輪增量進行了可視化。在P100 GPU上,每個網絡的測試需要花費1小時,進化共7000輪,200張卡共需要1.5天

Architecture Evaluation on CIFAR-10 and ImageNet

CONCLUSION

  論文基於層級表達提出高效的進化算法來進行神經網絡結構搜索,通過層層堆疊來構建強大的卷積結構。論文的搜索方法簡單,從實驗結果看來,200張卡共需要1.5天,達到很不錯的準確率,值得學習

APPENDIX A



如果本文對你有幫助,麻煩點個贊或在看唄~
更多內容請關注 微信公眾號【曉飛的算法工程筆記】

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

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

深入理解React:事件機制原理

目錄

  • 序言
  • DOM事件流
    • 事件捕獲階段、處於目標階段、事件冒泡階段
    • addEventListener 方法
  • React 事件概述
  • 事件註冊
    • document 上註冊
    • 回調函數存儲
  • 事件分發
  • 小結
  • 參考

1.序言

React 有一套自己的事件系統,其事件叫做合成事件。為什麼 React 要自定義一套事件系統?React 事件是如何註冊和觸發的?React 事件與原生 DOM 事件有什麼區別?帶着這些問題,讓我們一起來探究 React 事件機制的原理。為了便於理解,此篇分析將盡可能用圖解代替貼 React 源代碼進行解析。

2.DOM事件流

首先,在正式講解 React 事件之前,有必要了解一下 DOM 事件流,其包含三個流程:事件捕獲階段、處於目標階段和事件冒泡階段。

W3C協會早在1988年就開始了DOM標準的制定,W3C DOM標準可以分為 DOM1、DOM2、DOM3 三個版本。

從 DOM2 開始,DOM 的事件傳播分三個階段進行:事件捕獲階段、處於目標階段和事件冒泡階段。

(1)事件捕獲階段、處於目標階段和事件冒泡階段

示例代碼:

<html>
    <body>
        <div id="outer">
	    <p id="inner">Click me!</p>
	</div>
    </body>
</html>

上述代碼,如果點擊 <p>元素,那麼 DOM 事件流如下圖:

(1)事件捕獲階段:事件對象通過目標節點的祖先 Window 傳播到目標的父節點。

(2)處於目標階段:事件對象到達事件目標節點。如果阻止事件冒泡,那麼該事件對象將在此階段完成后停止傳播。

(3)事件冒泡階段:事件對象以相反的順序從目標節點的父項開始傳播,從目標節點的父項開始到 Window 結束。

(2)addEventListener 方法

DOM 的事件流中同時包含了事件捕獲階段和事件冒泡階段,而作為開發者,我們可以選擇事件處理函數在哪一個階段被調用。

addEventListener() 方法用於為特定元素綁定一個事件處理函數。addEventListener 有三個參數:

element.addEventListener(event, function, useCapture)

另外,如果一個元素(element)針對同一個事件類型(event),多次綁定同一個事件處理函數(function),那麼重複的實例會被拋棄。當然如果第三個參數capture值不一致,此時就算重複定義,也不會被拋棄掉。

3.React 事件概述

React 根據W3C 規範來定義自己的事件系統,其事件被稱之為合成事件 (SyntheticEvent)。而其自定義事件系統的動機主要包含以下幾個方面:

(1)抹平不同瀏覽器之間的兼容性差異。最主要的動機。

(2)事件”合成”,即事件自定義。事件合成既可以處理兼容性問題,也可以用來自定義事件(例如 React 的 onChange 事件)。

(3)提供一個抽象跨平台事件機制。類似 VirtualDOM 抽象了跨平台的渲染方式,合成事件(SyntheticEvent)提供一個抽象的跨平台事件機制。

(4)可以做更多優化。例如利用事件委託機制,幾乎所有事件的觸發都代理到了 document,而不是 DOM 節點本身,簡化了 DOM 事件處理邏輯,減少了內存開銷。(React 自身模擬了一套事件冒泡的機制)

(5)可以干預事件的分發。V16引入 Fiber 架構,React 可以通過干預事件的分發以優化用戶的交互體驗。

注:「幾乎」所有事件都代理到了 document,說明有例外,比如audiovideo標籤的一些媒體事件(如 onplay、onpause 等),是 document 所不具有,這些事件只能夠在這些標籤上進行事件進行代理,但依舊用統一的入口分發函數(dispatchEvent)進行綁定。

4.事件註冊

React 的事件註冊過程主要做了兩件事:document 上註冊、存儲事件回調。

(1)document 上註冊

在 React 組件掛載階段,根據組件內的聲明的事件類型(onclick、onchange 等),在 document 上註冊事件(使用addEventListener),並指定統一的回調函數 dispatchEvent。換句話說,document 上不管註冊的是什麼事件,都具有統一的回調函數 dispatchEvent。也正是因為這一事件委託機制,具有同樣的回調函數 dispatchEvent,所以對於同一種事件類型,不論在 document 上註冊了幾次,最終也只會保留一個有效實例,這能減少內存開銷。

示例代碼:

function TestComponent() {
  handleFatherClick=()=>{
		// ...
  }

  handleChildClick=()=>{
		// ...
  }

  return <div className="father" onClick={this.handleFatherClick}>
	<div className="child" onClick={this.handleChildClick}>child </div>
  </div>
}

上述代碼中,事件類型都是onclick,由於 React 的事件委託機制,會指定統一的回調函數 dispatchEvent,所以最終只會在 document 上保留一個 click 事件,類似document.addEventListener('click', dispatchEvent),從這裏也可以看出 React 的事件是在 DOM 事件流的冒泡階段被觸發執行。

(2)存儲事件回調

React 為了在觸發事件時可以查找到對應的回調去執行,會把組件內的所有事件統一地存放到一個對象中(listenerBank)。而存儲方式如上圖,首先會根據事件類型分類存儲,例如 click 事件相關的統一存儲在一個對象中,回調函數的存儲採用鍵值對(key/value)的方式存儲在對象中,key 是組件的唯一標識 id,value 對應的就是事件的回調函數。

React 的事件註冊的關鍵步驟如下圖:

5.事件分發

事件分發也就是事件觸發。React 的事件觸發只會發生在 DOM 事件流的冒泡階段,因為在 document 上註冊時就默認是在冒泡階段被觸發執行。

其大致流程如下:

  1. 觸發事件,開始 DOM 事件流,先後經過三個階段:事件捕獲階段、處於目標階段和事件冒泡階段
  2. 當事件冒泡到 document 時,觸發統一的事件分發函數 ReactEventListener.dispatchEvent
  3. 根據原生事件對象(nativeEvent)找到當前節點(即事件觸發節點)對應的 ReactDOMComponent 對象
  4. 事件的合成
    1. 根據當前事件類型生成對應的合成對象
    2. 封裝原生事件對象和冒泡機制
    3. 查找當前元素以及它所有父級
    4. 在 listenerBank 中查找事件回調函數併合成到 events 中
  5. 批量執行合成事件(events)內的回調函數
  6. 如果沒有阻止冒泡,會將繼續進行 DOM 事件流的冒泡(從 document 到 window),否則結束事件觸發

注:上圖中阻止冒泡是指調用stopImmediatePropagation 方法阻止冒泡,如果是調用stopPropagation阻止冒泡,document 上如果還註冊了同類型其他的事件,也將會被觸發執行,但會正常阻斷 window 上事件觸發。了解兩者之間的詳細區別

示例代碼:

class TestComponent extends React.Component {

  componentDidMount() {
    this.parent.addEventListener('click', (e) => {
      console.log('dom parent');
    })
    this.child.addEventListener('click', (e) => {
      console.log('dom child');
    })
    document.addEventListener('click', (e) => {
      console.log('document');
    })
    document.body.addEventListener('click', (e) => {
      console.log('body');
    })
    window.addEventListener('click', (e) => {
      console.log('window');
    })
  }

  childClick = (e) => {
    console.log('react child');
  }

  parentClick = (e) => {
    console.log('react parent');
  }

  render() {
    return (
      <div class='parent' onClick={this.parentClick} ref={ref => this.parent = ref}>
        <div class='child' onClick={this.childClick} ref={ref => this.child = ref}>
          Click me!
        </div>
      </div>)
  }
}

點擊 child div 時,其輸出如下:

在 DOM 事件流的冒泡階段先後經歷的元素:child <div> -> parent <div> -> <body> -> <html> -> document -> window,因此上面的輸出符合預期。

6.小結

React 合成事件和原生 DOM 事件的主要區別:

(1)React 組件上聲明的事件沒有綁定在 React 組件對應的原生 DOM 節點上。

(2)React 利用事件委託機制,將幾乎所有事件的觸發代理(delegate)在 document 節點上,事件對象(event)是合成對象(SyntheticEvent),不是原生事件對象,但通過 nativeEvent 屬性訪問原生事件對象。

(3)由於 React 的事件委託機制,React 組件對應的原生 DOM 節點上的事件觸發時機總是在 React 組件上的事件之前。

7.參考

javascript中DOM0,DOM2,DOM3級事件模型解析

Event dispatch and DOM event flow

EventTarget.addEventListener() – Web API 接口參考| MDN

合成事件

談談React事件機制和未來(react-events)

React源碼解讀系列 – 事件機制

一文吃透 react 事件機制原理

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

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

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

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

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

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

※回頭車貨運收費標準

BMW i3 在美銷量 首度超越 Tesla Model S

 

BMW i3 純電動汽車今年 8 月在美銷量為 1,025 輛,首次超過特斯拉 Model S,後者 8 月銷量僅為 600 輛。

寶馬 i3 純電動車型在美國市場已上市 3 個月,之前由於寶馬內部的運轉效率問題,其銷量一直低於特斯拉 Model S。但該問題解決後,寶馬 i3 的銷量也迎頭趕上。特斯拉 8 月整體需求較去年同期下降 54%,7 月更是下降了 72%。與 2013 年同期相比,特斯拉今年上半年銷量下降了 26%。

專家稱,特斯拉目前正處發展壯大的階段,而寶馬在歐洲和亞洲市場則以紮穩腳跟。在產品創新度、更新速度及售價方面,特斯拉 Model S 的優勢愈來愈不明顯,而隨著寶馬 i3 的銷量逐步上升,預計歐洲將會成為其最大銷售市場。

 

(圖片來源:)

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

【其他文章推薦】

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

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

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

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

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

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