CNN實作Kaggle貓狗影像辨識(Pytorch)

更新於 2024/01/05閱讀時間約 27 分鐘
最近剛好修了Pytorch相關的課,在Kaggle上也丟了個比賽,想說就來分享一下Pytorch的入門實戰,我會實作一個最入門的用CNN辨識貓狗的程式,但關於CNN理論的部分我不會提到太多,有興趣就麻煩再去搜尋了~

CNN是什麼?

先簡單介紹一下CNN,CNN的全名是(Convolutional Neural Network),中文是卷積神經網路,是機器學習中的深度學習的一種,也是目前應用於影像辨識非常熱門的一種模型。

資料集準備

我這次使用Kaggle的貓狗資料集,可以先下載下來,總共有三個檔案分別是訓練集train(包含貓狗各12500張圖片),以及測試集test(12500張未分類的圖片),和sample_submission。由於小弟太窮沒錢買GPU且為了節省時間,我先把貓和狗各挑了100張圖片,並分別放到自建的dog和cat資料夾內。
來源:Pixabay

程式實作

載入需要的Library

import torch
import torch.nn as nn
from torchvision import datasets ,models,transforms
from pathlib import Path
from matplotlib import pyplot as plt
import numpy as np
import torch.nn.functional as F
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from torch.nn import Linear, ReLU, CrossEntropyLoss, Conv2d, MaxPool2d, Module
from torch.optim import Adam
import pandas as pd
import os
from os import listdir
from tqdm import tqdm_notebook as tqdm
from PIL import Image

準備資料、設定超參數

Path_train填入自己的資料夾路徑,我的train裡面有dog和cat的資料夾,分別有各100張圖,並設定Batch和Learning Rate,transforms函數可以將圖片轉成(224,224)的像素,同時將圖片轉成Pytorch能讀取的tensor格式。
PATH_train="...../train"
TRAIN =Path(PATH_train)
#Batch:每批丟入多少張圖片
batch_size = 8
#Learning Rate:學習率
LR = 0.0001
transforms = transforms.Compose([transforms.Resize((224,224)), transforms.ToTensor()]

切分訓練驗證集

用ImageFolder讀取檔案並套入前面transforms的轉換函數,ImageFolder會把圖片根據資料夾給予label,可以用class_to_idx查詢貓和狗分別對應的label,print出來的結果會像這樣。
{‘cat’: 0, ‘dog’: 1}
注意ImageFolder必須在資料夾內有子資料夾才可使用,所以我先分別把貓和狗的圖放進cat和dog的資料夾。
train_data = datasets.ImageFolder(TRAIN, transform=transforms)
#print(train_data.class_to_idx)
#切分70%當作訓練集、30%當作驗證集
train_size = int(0.7 * len(train_data))
valid_size = len(train_data) - train_size
train_data, valid_data = torch.utils.data.random_split(train_data, [train_size, valid_size])
#Dataloader可以用Batch的方式訓練
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size,shuffle=True)
valid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,shuffle=True)

建立CNN的架構

這邊要定義自己的CNN架構,我用最簡單的範例,基本上CNN最主要就是ConvolutionalMaxpool兩種層所組成,Relu是激發函數,然後最後要用線性層輸出預測結果,因為貓狗是兩個種類,所以Linear後面的參數就是2,輸出結果如[0.487,0.9527],index為1的狗比較大,代表預測結果為狗。
最後也可以加一層Softmax讓兩者機率加起來為1如[0.7,0.3])
Pytorch最少要定義兩個function,一個是__init__,用來建立你forward需要用到哪些層,另一個是forward,也就是定義路徑要怎麼走,不需另外定義Backward,Pytorch會自動幫你設定Back-propagation的路徑。
至於參數的設定我這邊簡單講一下
self.cnn1=nn.Conv2d(3,16,kernal_size=5,stride=1)
3代表input的channel,因為圖片是RGB所以是3,16代表output的channel,這邊我用了16個hidden node所以為16,kernel_size是5*5的filter。
self.maxpool1 = nn.MaxPool2d(kernel_size=2)
這裡的kernel_size代表2*2的格子取最大的一格,會將8*8縮成4*4。
self.fc = nn.Linear(8 * 50 * 50, 2)
至於線性層為何是(8*50*50,2),根據下面這個公式算出下一層的shape,如原圖是(3,224,224)經過cnn1後,(224–5+1)/(1+1)=110,因此maxpool1的input就變成(16,110,110),而Maxpool1的kernal_size為2,因此output就變成(16,55,55),以此類推最後的Shape就變成(8*50*50,2)。
(weight-kernel+1)/stride+1 無條件進位
class CNN_Model(nn.Module):
#列出需要哪些層
def __init__(self):
super(CNN_Model, self).__init__()
# Convolution 1 , input_shape=(3,224,224)
self.cnn1 = nn.Conv2d(3, 16, kernel_size=5, stride=1)
self.relu1 = nn.ReLU(inplace=True)
# Max pool 1
self.maxpool1 = nn.MaxPool2d(kernel_size=2)
# Convolution 2
self.cnn2 = nn.Conv2d(16,8, kernel_size=11, stride=1)
self.relu2 = nn.ReLU(inplace=True)
# Max pool 2
self.maxpool2 = nn.MaxPool2d(kernel_size=2)
# Fully connected 1 ,#input_shape=(8*50*50)
self.fc = nn.Linear(8 * 50 * 50, 2)
#列出forward的路徑,將init列出的層代入
def forward(self, x):
out = self.cnn1(x)
out = self.relu1(out)
out = self.maxpool1(out)
out = self.cnn2(out)
out = self.relu2(out)
out = self.maxpool2(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return out

定義訓練過程、計算Loss、Accuracy

Tdqm訓練過程圖
這邊先將訓練、驗證模組化,傳入的函數包含model(要使用的模型)、n_epochs(迭代次數)、train_loader、valid_loader(訓練、驗證集)、optimizer(優化器)、Criterion(損失函數)。
1.train_loss和valid loss是算出每個batch的平均loss
2.tqdm可以很好的跟data製作出進度條(如上圖)
3.model.eval()會關閉batchnorm、dropout,雖這範例沒有,但一般都會用到
4.output.data.max用來輸出較大的index如[0.487,0.9527],則輸出1 P
5.Validation階段不需做BP,所以少了幾步
def train(model,n_epochs,train_loader,valid_loader,optimizer,criterion):
train_acc_his,valid_acc_his=[],[]
train_losses_his,valid_losses_his=[],[]
for epoch in range(1, n_epochs+1):
# keep track of training and validation loss
train_loss,valid_loss = 0.0,0.0
train_losses,valid_losses=[],[]
train_correct,val_correct,train_total,val_total=0,0,0,0
train_pred,train_target=torch.zeros(8,1),torch.zeros(8,1)
val_pred,val_target=torch.zeros(8,1),torch.zeros(8,1)
count=0
count2=0
print('running epoch: {}'.format(epoch))
###################
# train the model #
###################
model.train()
for data, target in tqdm(train_loader):
# move tensors to GPU if CUDA is available
if train_on_gpu:
data, target = data.cuda(), target.cuda()
# forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the batch loss
loss = criterion(output, target)
#calculate accuracy
pred = output.data.max(dim = 1, keepdim = True)[1]
train_correct += np.sum(np.squeeze(pred.eq(target.data.view_as(pred))).cpu().numpy())
train_total += data.size(0)
# backward pass: compute gradient of the loss with respect to model parameters
loss.backward()
# perform a single optimization step (parameter update)
optimizer.step()
# update training loss
train_losses.append(loss.item()*data.size(0))
# clear the gradients of all optimized variables
optimizer.zero_grad()
if count==0:
train_pred=pred
train_target=target.data.view_as(pred)
count=count+1
else:
train_pred=torch.cat((train_pred,pred), 0)
train_target=torch.cat((train_target,target.data.view_as(pred)), 0)
train_pred=train_pred.cpu().view(-1).numpy().tolist()
train_target=train_target.cpu().view(-1).numpy().tolist()
######################    
# validate the model #
######################
model.eval()
for data, target in tqdm(valid_loader):
# move tensors to GPU if CUDA is available
if train_on_gpu:
data, target = data.cuda(), target.cuda()
# forward pass: compute predicted outputs by passing inputs to the model
output = model(data)
# calculate the batch loss
loss =criterion(output, target)
#calculate accuracy
pred = output.data.max(dim = 1, keepdim = True)[1]
val_correct += np.sum(np.squeeze(pred.eq(target.data.view_as(pred))).cpu().numpy())
val_total += data.size(0)
valid_losses.append(loss.item()*data.size(0))
if count2==0:
val_pred=pred
val_target=target.data.view_as(pred)
count2=count+1
else:
val_pred=torch.cat((val_pred,pred), 0)
val_target=torch.cat((val_target,target.data.view_as(pred)), 0)
val_pred=val_pred.cpu().view(-1).numpy().tolist()
val_target=val_target.cpu().view(-1).numpy().tolist()

# calculate average losses
train_loss=np.average(train_losses)
valid_loss=np.average(valid_losses)

# calculate average accuracy
train_acc=train_correct/train_total
valid_acc=val_correct/val_total
train_acc_his.append(train_acc)
valid_acc_his.append(valid_acc)
train_losses_his.append(train_loss)
valid_losses_his.append(valid_loss)
# print training/validation statistics 
print('\tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
train_loss, valid_loss))
print('\tTraining Accuracy: {:.6f} \tValidation Accuracy: {:.6f}'.format(
train_acc, valid_acc))
return train_acc_his,valid_acc_his,train_losses_his,valid_losses_his,model

開始訓練囉~

首先初始化CNN_Model(),使用最常用的Adam作為Optimizer,由於是分類問題Loss Function選用CrossEntropy,代入函數即可以開始訓練囉!!
model1=CNN_Model()
n_epochs = 10
optimizer1 = torch.optim.Adam(model1.parameters(), lr=LR)
criterion = CrossEntropyLoss()
train_acc_his,valid_acc_his,train_losses_his,valid_losses_his,model1=train(model1,n_epochs,train_loader,valid_loader,optimizer1,criterion)

訓練結果、儲存Model

訓練結果圖
這邊就可以把剛剛訓練完的結果留下來,並畫成loss和accuracy(如上圖),檢驗訓練的狀況,由於訓練非常耗時間,可以用torch.save的函數把訓練好的model保存下來,之後就可以直接load進來用。
由於是做範例示範,所以用了很簡單的架構及非常少的data,所以從上面的圖可發現training和validation差非常遠,有非常嚴重的Overfitting的問題,因此之後可以再去進行調整。
plt.figure(figsize=(15,10))
plt.subplot(221)
plt.plot(train_losses_his, 'bo', label = 'training loss')
plt.plot(valid_losses_his, 'r', label = 'validation loss')
plt.title("Simple CNN Loss")
plt.legend(loc='upper left')
plt.subplot(222)
plt.plot(train_acc_his, 'bo', label = 'trainingaccuracy')
plt.plot(valid_acc_his, 'r', label = 'validation accuracy')
plt.title("Simple CNN Accuracy")
plt.legend(loc='upper left')
plt.show()
torch.save(model1, "....../Dogcat_resnet18")
#model1 = torch.load('..../Dogcat_resnet18')
接下來不斷調整找出最好的參數、架構即可,但注意調整太多次,Validation的效果可能會變差,也容易對Validation Set有Overfitting的問題,而影響模型對Test的泛用性,因此前面data_loader也用了shuffle的函數,把每次的batch洗散,切分資料集也沒使用random_state固定切分的資料。

用自己的CNN參加Kaggle競賽

由於網路上通常到上一步就結束了,但相信不少人也會想知道自己的模型到底好不好,所以我這邊會分享一下如何用自己設計的CNN參加Kaggle競賽。
由於Kaggle給的test集檔案為1.jpg,2.jpg…..因此先將檔案以PIL的格式讀取,在套入transforms的轉換。model的input是batch的方式讀取,因此會有4個維度(8,3,224,224),由於我們是一張一張讀取,所以model只有3個維度(3,224,224),因此在用unsqueeze(0)在0的index上加一個維度即變成(1,3,224,224),就可以預測了。
PS由於Dataloader輸出順序不固定,所以提交部分就另外寫了一個function
def test_submit(model,n_img,path): 
model.eval()
pred_label=[]
for i in tqdm(range(1,n_img+1)):
path = image_path + str(i) +'.jpg'
img = Image.open(path).convert('RGB')
img = transforms(img)
img = img.unsqueeze(0)
with torch.no_grad():
output=model(img)
pred = output.data.max(dim = 1, keepdim = True)[1]
pred_label.append(int(pred))
return pred_label
最後把參數帶入,輸出成csv,提交到Kaggle的網站上,大功就告成啦!!
image_path =’.../test/’
n_img=12500
pred_label=test_submit(model1,n_img,image_path)
submit = pd.read_csv('.../sample_submission.csv')
submit['label'] = pred_label
submit['label'] = submit['label'].astype(int)
submit.to_csv('..../submit_dogcat.csv', index= False)
由於小弟我才疏學淺且第一次寫技術分享相關文章,可能有很多錯誤和不周延的地方,再請各位大神指教、糾正了,感謝大家~
若覺得有幫助可以追蹤我、按喜歡、收藏,我就會寫出更多相關文章,謝謝你~
若還有其他想問的或希望我介紹的,可以用FB私訊或在下面回應,我會盡我所能回答
你可能還會想看:
為什麼會看到廣告
avatar-img
1會員
37內容數
大學科系選擇技巧、高中升學考試經驗分享
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
吉米富的沙龍 的其他內容
分科測驗當年叫做指考,但文章以準備方式、考試技巧為主 數學科、社會科仍具參考性,有興趣就歡迎看下去吧! 這篇我會介紹我當年指考的準備經驗、方法、分科(甚至分題)技巧、參考書推薦,能講的我都全打了,提供給還在考慮要不要考分科測驗和確定轉戰分科測驗的學弟妹當作參考~~~ 指考前遇到的波折 學測失常,但還
又快到了投暑假實習的季節了,國泰CIP實習好像還挺熱門的,聽HR說每年的錄取率好像只有7%的樣子,我就來分享一下投履歷、面試到錄取的心得吧! 我投的部門是 國泰世華銀行 資訊處 的職位,我那屆資訊處錄取的總共好像十個人,而我最終錄取的是中台發展部,這個部門是近幾年才成立很新的部門,中台這個名字可能比
千島之國 先稍微簡單介紹個菲律賓宿霧,菲律賓是一個千島之國,所以要跳島都需要搭船,我坐的船都算蠻穩的,但位子會比較小一點。我這次主要是在宿霧島、薄荷島兩個島嶼,菲律賓共有7000多個島嶼,如果錢夠多的話可以考慮直接買幾個拿來度假XD 貨幣 菲律賓主要使用的貨幣是披索(peso),代號是PHP,最近匯
選校、選系? 延續上篇文章,這問題幾乎每年都在論壇上開戰,我必須說即使我念完大學四年也無法告訴你哪個是對的,因為真的非常因人而異,但鑒於高中生和大學、職場有各種資訊不對稱。我希望能就我所知,提供各層面的分析,最後會歸納我的建議提供評估作參考。 1.校名、找實習、第一份工作、研究所 不可否認現今台灣社
前幾天從菲律賓宿霧回來,想說很多人畢旅應該都會考慮到宿霧玩,來稍微介紹這幾天主要的行程,幾乎都是宿霧幾個必走的。 行程介紹 麥哲倫十字架、聖彼得堡、聖嬰大教堂 這三個點就是一般的拍照景點,幾乎是宿霧的必帶行程,充滿歷史故事的地方。麥哲倫十字架那可以跟一個人買蠟燭許願,他就會幫你祈福,儀式還挺特別的可
分科測驗當年叫做指考,但本文著重於優缺點分析、經驗分享 因此仍具部分參考性,有興趣就歡迎看下去吧! 除了選校、選系外一定不少人會猶豫要不要考分科測驗(指考),但多數人聽到分科測驗(指考),通常都會有「好難、好可怕、不想考」等印象,因此想用這篇破除一些刻板印象,並給還在猶豫要不要考的考生們一點建議和看
分科測驗當年叫做指考,但文章以準備方式、考試技巧為主 數學科、社會科仍具參考性,有興趣就歡迎看下去吧! 這篇我會介紹我當年指考的準備經驗、方法、分科(甚至分題)技巧、參考書推薦,能講的我都全打了,提供給還在考慮要不要考分科測驗和確定轉戰分科測驗的學弟妹當作參考~~~ 指考前遇到的波折 學測失常,但還
又快到了投暑假實習的季節了,國泰CIP實習好像還挺熱門的,聽HR說每年的錄取率好像只有7%的樣子,我就來分享一下投履歷、面試到錄取的心得吧! 我投的部門是 國泰世華銀行 資訊處 的職位,我那屆資訊處錄取的總共好像十個人,而我最終錄取的是中台發展部,這個部門是近幾年才成立很新的部門,中台這個名字可能比
千島之國 先稍微簡單介紹個菲律賓宿霧,菲律賓是一個千島之國,所以要跳島都需要搭船,我坐的船都算蠻穩的,但位子會比較小一點。我這次主要是在宿霧島、薄荷島兩個島嶼,菲律賓共有7000多個島嶼,如果錢夠多的話可以考慮直接買幾個拿來度假XD 貨幣 菲律賓主要使用的貨幣是披索(peso),代號是PHP,最近匯
選校、選系? 延續上篇文章,這問題幾乎每年都在論壇上開戰,我必須說即使我念完大學四年也無法告訴你哪個是對的,因為真的非常因人而異,但鑒於高中生和大學、職場有各種資訊不對稱。我希望能就我所知,提供各層面的分析,最後會歸納我的建議提供評估作參考。 1.校名、找實習、第一份工作、研究所 不可否認現今台灣社
前幾天從菲律賓宿霧回來,想說很多人畢旅應該都會考慮到宿霧玩,來稍微介紹這幾天主要的行程,幾乎都是宿霧幾個必走的。 行程介紹 麥哲倫十字架、聖彼得堡、聖嬰大教堂 這三個點就是一般的拍照景點,幾乎是宿霧的必帶行程,充滿歷史故事的地方。麥哲倫十字架那可以跟一個人買蠟燭許願,他就會幫你祈福,儀式還挺特別的可
分科測驗當年叫做指考,但本文著重於優缺點分析、經驗分享 因此仍具部分參考性,有興趣就歡迎看下去吧! 除了選校、選系外一定不少人會猶豫要不要考分科測驗(指考),但多數人聽到分科測驗(指考),通常都會有「好難、好可怕、不想考」等印象,因此想用這篇破除一些刻板印象,並給還在猶豫要不要考的考生們一點建議和看
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
卷積神經網路(CNN)是一種專門用於影像相關應用的神經網路。本文介紹了CNN在影像辨識中的應用,包括圖片的組成、Receptive Field、Parameter Sharing、以及Pooling等技術。通過本文,讀者將瞭解CNN在影像辨識領域的優勢和運作原理。
Thumbnail
台灣各地有許多難得一見到地理景觀現。這篇介紹老梅石槽。老梅石槽是全台灣唯一少見的特殊景觀,更是萬年才形成地理景觀。綠油油的一片又一片海藻與海水及白沙相呼應、形成美麗的藍綠白穿梭色彩風光,這裡是季節性特殊地景。 老梅石槽相關資訊:: ​地址: 新北市石門區老梅里東海海岸線 ​電話: 02
Thumbnail
前言 上一篇討論到如何訓練出模型,此篇將說明Streamlit建立的簡單Web應用程式的解說 Streamlit網頁App_貓狗辨識 連結 程式碼Github連結 [機器學習]CNN學習MNIST 手寫英文字母資料,用網頁展現成果_模型訓練篇 如何連動github與stramlit可以參考
Thumbnail
streamlit與github連動程式庫,呈現即時預測手寫英文字母 整理了一下,先前學的機器學習利用Colab來訓練出能辨識手寫A~Z英文字母的模型,使用的模型是CNN(Convolutional Neural Network,CNN)模型 訓練好的模型,當然是要拿來應用,成果呈現
Thumbnail
​ 餐車在許多市集與活動時常會看到,餐車對比店面具有快速出餐、便利速度等優點。新巨輪服務協會的餐車更是一個很特別餐車,新巨輪服務協會首創全台灣無障礙餐車,由障礙者擔任餐車大廚,致力讓全台灣吃到最有公益價值的餐車美食。 新巨輪服務協會餐車相關資訊:: ​地址: 新北市土城區承天路43巷10號
Thumbnail
​ 嚭香便宜好吃、又吃得飽的平民餐店,隨便點一個餐食,只要你是正常人都會吃飽這家店。這家店每到用餐時間總是來店家吃飯很多人。平民餐食這家絕對是很棒店家。 嚭香相關資訊:: ​地址: 台北市中正區八德路一段82巷9弄9號 ​營業時間: AM10:30-PM20:30 (店休日:周日)
Thumbnail
藉由CNN時是新聞標題及歐美制度的歷史背景,深入學習mercenary(圖利的) 、commerce(商業;貿易)、commercial(電視、廣播)商業廣告)、commercialize(使商業化,使商品化)、merchant(商人)、merchandise(商品;貨物)六個同字根的英文生字用法。
Thumbnail
月子餐每日基本營養分配 中藥補湯(湯800-1000cc、肉類蛋白質) 肉類料理2道(蛋白質)午餐跟晚餐各一 蔬菜料理2道(纖維)午餐跟晚餐各一 常備菜3-4道(纖維、蛋白質) 主食1-2種(澱粉熱量) 水果2-3種(維他命) 中藥茶1種(800-1000cc) 飲料1種(800-1000cc)
Thumbnail
閱讀CNN商業新聞,增廣自己跨領域學習商用英文外,也讓自己培養(國際)宏觀觀點,進行個人的微觀理財及職涯規劃。
Thumbnail
#葉郎時光機 [ 1991年1月17日:美軍沙漠風暴行動造就了CNN的新聞盛世 ] 才剛剛寫信向員工告解並稱會努力喚回員工信任的 CNN 執行長 Chris Licht ,不到24小時內就傳出已經向母公司 Warner Bros. Discovery 執行長 David Zaslav 提出辭呈,結束
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
卷積神經網路(CNN)是一種專門用於影像相關應用的神經網路。本文介紹了CNN在影像辨識中的應用,包括圖片的組成、Receptive Field、Parameter Sharing、以及Pooling等技術。通過本文,讀者將瞭解CNN在影像辨識領域的優勢和運作原理。
Thumbnail
台灣各地有許多難得一見到地理景觀現。這篇介紹老梅石槽。老梅石槽是全台灣唯一少見的特殊景觀,更是萬年才形成地理景觀。綠油油的一片又一片海藻與海水及白沙相呼應、形成美麗的藍綠白穿梭色彩風光,這裡是季節性特殊地景。 老梅石槽相關資訊:: ​地址: 新北市石門區老梅里東海海岸線 ​電話: 02
Thumbnail
前言 上一篇討論到如何訓練出模型,此篇將說明Streamlit建立的簡單Web應用程式的解說 Streamlit網頁App_貓狗辨識 連結 程式碼Github連結 [機器學習]CNN學習MNIST 手寫英文字母資料,用網頁展現成果_模型訓練篇 如何連動github與stramlit可以參考
Thumbnail
streamlit與github連動程式庫,呈現即時預測手寫英文字母 整理了一下,先前學的機器學習利用Colab來訓練出能辨識手寫A~Z英文字母的模型,使用的模型是CNN(Convolutional Neural Network,CNN)模型 訓練好的模型,當然是要拿來應用,成果呈現
Thumbnail
​ 餐車在許多市集與活動時常會看到,餐車對比店面具有快速出餐、便利速度等優點。新巨輪服務協會的餐車更是一個很特別餐車,新巨輪服務協會首創全台灣無障礙餐車,由障礙者擔任餐車大廚,致力讓全台灣吃到最有公益價值的餐車美食。 新巨輪服務協會餐車相關資訊:: ​地址: 新北市土城區承天路43巷10號
Thumbnail
​ 嚭香便宜好吃、又吃得飽的平民餐店,隨便點一個餐食,只要你是正常人都會吃飽這家店。這家店每到用餐時間總是來店家吃飯很多人。平民餐食這家絕對是很棒店家。 嚭香相關資訊:: ​地址: 台北市中正區八德路一段82巷9弄9號 ​營業時間: AM10:30-PM20:30 (店休日:周日)
Thumbnail
藉由CNN時是新聞標題及歐美制度的歷史背景,深入學習mercenary(圖利的) 、commerce(商業;貿易)、commercial(電視、廣播)商業廣告)、commercialize(使商業化,使商品化)、merchant(商人)、merchandise(商品;貨物)六個同字根的英文生字用法。
Thumbnail
月子餐每日基本營養分配 中藥補湯(湯800-1000cc、肉類蛋白質) 肉類料理2道(蛋白質)午餐跟晚餐各一 蔬菜料理2道(纖維)午餐跟晚餐各一 常備菜3-4道(纖維、蛋白質) 主食1-2種(澱粉熱量) 水果2-3種(維他命) 中藥茶1種(800-1000cc) 飲料1種(800-1000cc)
Thumbnail
閱讀CNN商業新聞,增廣自己跨領域學習商用英文外,也讓自己培養(國際)宏觀觀點,進行個人的微觀理財及職涯規劃。
Thumbnail
#葉郎時光機 [ 1991年1月17日:美軍沙漠風暴行動造就了CNN的新聞盛世 ] 才剛剛寫信向員工告解並稱會努力喚回員工信任的 CNN 執行長 Chris Licht ,不到24小時內就傳出已經向母公司 Warner Bros. Discovery 執行長 David Zaslav 提出辭呈,結束