묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)
Transformer 번역기 부분에 대해 질문 있습니다.
아래 사이트는 Encoder / Decoder를 하나의 Class로 만들었는데요..강사님도 해당 예제는 많이 보셨을거 같습니다.https://keras.io/examples/nlp/neural_machine_translation_with_transformer/ 아래와 같이 Encoder / Decoder Class를 선언하고..추가로 shape들을 찍어 보았습니다.(참고로 get_config 함수는 지면상 뺐습니다.)class TransformerEncoder(keras.layers.Layer): def init(self, num_heads, embed_dim, dense_dim, **kwargs): super().__init__(**kwargs) self.num_heads = num_heads self.embed_dim = embed_dim self.dense_dim = dense_dim self.class_name = 'TransformerEncoder' self.attention = keras.layers.MultiHeadAttention(self.num_heads, key_dim=self.embed_dim, value_dim=self.embed_dim) self.dense = keras.models.Sequential([keras.layers.Dense(self.dense_dim, activation='relu'), keras.layers.Dense(self.embed_dim)]) self.layer1 = keras.layers.LayerNormalization() self.layer2 = keras.layers.LayerNormalization() self.support_mask = True def call(self, inputs, mask=None): tf.print('ClassName=TransformerEncoder-------------------------------------------------------') if mask is not None: #print('ClassName={}, mask.shape={}'.format(self.class_name, mask.shape)) padding_mask = mask[:, tf.newaxis, :] tf.print('mask.shape=', padding_mask.shape) else: padding_mask = None tf.print('mask=None') attention_out = self.attention(query=inputs, key=inputs, value=inputs, attention_mask=padding_mask) tf.print('input.shape=', inputs.shape) tf.print('attention_out.shape=', attention_out.shape) layer1_out = self.layer1(inputs+attention_out) #print('ClassName={}, layer1_out.shape={}'.format(self.class_name, layer1_out.shape)) dense_out = self.dense(layer1_out) tf.print('dense_out.shape=', dense_out.shape) return self.layer2(layer1_out+dense_out) class TransformerDecoder(keras.layers.Layer): def init(self, num_heads, embed_dim, latent_dim, **kwargs): super().__init__(**kwargs) self.num_heads = num_heads self.embed_dim = embed_dim self.latent_dim = latent_dim self.class_name = 'Decoder' self.attention_1 = keras.layers.MultiHeadAttention(num_heads=self.num_heads, key_dim=self.embed_dim) self.attention_2 = keras.layers.MultiHeadAttention(num_heads=self.num_heads, key_dim=self.embed_dim) self.layer_1 = keras.layers.LayerNormalization() self.layer_2 = keras.layers.LayerNormalization() self.layer_3 = keras.layers.LayerNormalization() self.dense = keras.models.Sequential([keras.layers.Dense(self.latent_dim, activation='relu'), keras.layers.Dense(self.embed_dim)]) self.supports_masking=True def call(self, inputs, encoder_outputs, mask=None): tf.print('ClassName=TransformerDecoder-------------------------------------------------------') #inputs.shape=(None, 35, 32), encoder_outputs.shape=(None, 35, 32) #tf.print('aaaaaaaaa=', inputs.shape) casual_mask = self.get_casual_attention_mask(inputs) tf.print('inputs.shape=', inputs.shape) tf.print('casual_mask.shape=', casual_mask.shape) if mask is not None: padding_mask = tf.cast(mask[:, None, :], dtype='int32') padding_mask = tf.minimum(padding_mask, casual_mask) tf.print('padding_mask.shape=', padding_mask.shape) else: padding_mask = None tf.print('padding_mask = None') attention_1_out = self.attention_1(query=inputs, key=inputs, value=inputs, attention_mask=casual_mask) tf.print('attention_1_out.shape=', attention_1_out.shape) layer_1_out = self.layer_1(inputs+attention_1_out) attention_2_out = self.attention_2(query=layer_1_out, key=encoder_outputs, value=encoder_outputs, attention_mask=padding_mask) layer_2_out = self.layer_2(layer_1_out + attention_2_out) dense_out = self.dense(layer_2_out) tf.print('dense_out.shape=', dense_out.shape) return self.layer_3(layer_2_out + dense_out) def get_casual_attention_mask(self, inputs): #input_shape=(2, 35, 32) =(BatchSize, Sequence_len, Embed_Len) input_shape = tf.shape(inputs) batch_size, sequence_length = input_shape[0], input_shape[1] #i=(35, 1), j=(35,) #i=[[0], [1], [2], ... [35]], j=[0 1 2 ... 34] i = tf.range(start=0, limit=sequence_length)[:, tf.newaxis] j = tf.range(start=0, limit=sequence_length) # tf.cast 함수는 보통 조건에 따른 True, False 의 판단 기준에 따라 True 면 1, False 면 0을 반환한다. # mask.shape=(1, 35, 35), mask=[[[1 0 0 .. 0], [1 1 0 0 ...0], [1 1 1 1 ...1 0], [1 1 1 1 ... 1 1]]] mask = tf.cast(i>=j, dtype='int32') mask = tf.reshape(mask, (1, input_shape[1], input_shape[1])) # mult = (2, 1, 1), (BatchSize, 1, 1) mult = tf.concat([tf.expand_dims(batch_size, -1), tf.convert_to_tensor([1,1])], axis=0) return tf.tile(mask, mult) MAX_EMBED=32 MAX_VOCAB=5000 MAX_SEQ = 35 MAX_DENSE=1024 MAX_HEAD=1 encoder_inputs = keras.layers.Input(shape=(MAX_SEQ,), dtype='int64', name='encoder_inputs') encoder_embed_outs = PositionalEmbedding(MAX_SEQ, MAX_VOCAB, MAX_EMBED)(encoder_inputs) encoder_transformer_outs = TransformerEncoder(num_heads=1, embed_dim=MAX_EMBED, dense_dim=MAX_DENSE)(encoder_embed_outs) #encoder_transformer_outs == (None, 80, 256) decoder_inputs = keras.layers.Input(shape=(MAX_SEQ,), dtype='int64', name='decoder_inputs') decoder_embed_outs = PositionalEmbedding(MAX_SEQ, MAX_VOCAB, MAX_EMBED)(decoder_inputs) #decoder_embed_outs == (None, 80, 256) decoder_transformer_outs = TransformerDecoder(1, MAX_EMBED, MAX_DENSE)(decoder_embed_outs, encoder_transformer_outs) decoder_dropout_outs = keras.layers.Dropout(0.5)(decoder_transformer_outs) decoder_outputs = keras.layers.Dense(MAX_VOCAB, activation='softmax')(decoder_dropout_outs) model = keras.Model(inputs=[encoder_inputs, decoder_inputs], outputs=decoder_outputs) model.summary() 호출(호출은 Log만 찍어보게 BatchSize를 줄였습니다.)q_train_seqs = q_seqs[:2] a_train_seqs = a_seqs[:2] print(q_train_seqs.shape, a_train_seqs.shape) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) history = model.fit([q_train_seqs, a_train_seqs[:, :-1]], a_train_seqs[:, 1:], epochs=1) 이렇게 해서 돌리면 결과가 아래와 같이 찍힙니다.ClassName=TransformerEncoder------------------------------------------------------- mask=None input.shape= TensorShape([None, 35, 32]) attention_out.shape= TensorShape([None, 35, 32]) dense_out.shape= TensorShape([None, 35, 32]) ClassName=TransformerDecoder------------------------------------------------------- inputs.shape= TensorShape([None, 35, 32]) casual_mask.shape= TensorShape([None, 35, 35]) padding_mask = None attention_1_out.shape= TensorShape([None, 35, 32]) dense_out.shape= TensorShape([None, 35, 32]) 1/1 [==============================] - 4s 4s/step - loss: 8.2735 - accuracy: 0.0000e+00 질문은 아래와 같습니다.Encoder 파트에서 mask=None 으로 Mask가 들어있지 않습니다. 그럼 굳이 mask는 구현할 필요가 없는건지? Decoder 파트에서는 첫번째 Self-Attention 부분에서만 제대로된 마스킹 값이 들어가고 Encoder의 Key와 매핑 시키는 부분에서는 마찬가지로 padding_mask가 None 입니다. 이 부분에 대해 조금 더 자세한 설명을 해 주시면 감사하겠습니다. 다시 한번 설명 드리면class TransformerEncoder(keras.layers.Layer): ... def call(self, inputs, mask=None): tf.print('ClassName=TransformerEncoder-------------------------------------------------------') if mask is not None: #print('ClassName={}, mask.shape={}'.format(self.class_name, mask.shape)) padding_mask = mask[:, tf.newaxis, :] tf.print('mask.shape=', padding_mask.shape) else: padding_mask = None tf.print('mask=None') #Encoder 에서 padding_mask는 None으로 찍힘 attention_out = self.attention(query=inputs, key=inputs, value=inputs, attention_mask=padding_mask) class TransformerDecoder(keras.layers.Layer): def call(self, inputs, encoder_outputs, mask=None): casual_mask = self.get_casual_attention_mask(inputs) #mask는 None 으로 들어옴 if mask is not None: padding_mask = tf.cast(mask[:, None, :], dtype='int32') padding_mask = tf.minimum(padding_mask, casual_mask) else: padding_mask = None # casual_mask는 현재 위치 이후는 0 으로 패딩 된 것 확인 attention_1_out = self.attention_1(query=inputs, key=inputs, value=inputs, attention_mask=casual_mask) layer_1_out = self.layer_1(inputs+attention_1_out) # 하지만 padding_mask는 None 임 attention_2_out = self.attention_2(query=layer_1_out, key=encoder_outputs, value=encoder_outputs, attention_mask=padding_mask) layer_2_out = self.layer_2(layer_1_out + attention_2_out)
-
미해결[무료]기초 텍스트마이닝: 앱 리뷰 분석 with 파이썬(40분 완성)
앱 리뷰 크롤링시 질문드립니다.
안녕하세요 선생님~~ 구글 플레이 스토어 앱 크롤링 영상 참고해서 앱 리뷰를 수집중입니다. 앱리뷰가 만건이상 아주 많은 앱이라서 기간을 분할해서 조금씩 모으려고 하는데..데이터 설정기간을 과거 특정 시점부터 특정시점까지만 설정해서(예를 들어 2023. 1.1 부터 3.31 까지) 하면 수집건이 자꾸 0으로만 나오는데 시간이나 변수설정을 바꿔보아도 계속 0이 나오는데 방법은 없는 걸까요? ㅠㅠ 죄송하지만 관련해서 도움주신다면 정말 감사하겠습니다!!
-
미해결모두의 한국어 텍스트 분석과 자연어처리 with 파이썬
안녕하세요 선생님
안녕하세요 선생님대학교에서 캡스톤디자인을 수행하고 있는 학생입니다.판결문에서 사건의 원인,판결 결과,가중·감소 처벌 요소,키워드를 추출하고 싶은데 어떤 기술을 사용해야할지 막막하여 질문올리게 되었습니다. 거대언어모델은 지양하라고 교수님께서 말씀하셨습니다..ㅜ조언을 주신다면 감사하겠습니다.
-
미해결LLM 101: 2시간에 끝내는 All-In-One 코스! 나만의 Llama 채팅데모 프로젝트!
에러가 나네요
모든걸 잘 따라 했는데 아래와 같은 에러가 나네요,,, 윈도우10 환경 입니다.
-
해결됨딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)
320_Custom_Sentiment_Analysis_navermovie.ipynb 실행 시 오류 납니다.
안녕하세요,아래 예제도 오류가 납니다.320_Custom_Sentiment_Analysis_navermovie.ipynb수정 방법을 알고 싶습니다.pip install transformers[torch]` or pip install accelerate -U 이 부분은 수행했는데도 발생합니다.확인 부탁 드립니다. ImportError Traceback (most recent call last) <ipython-input-50-ed29579c1c8b> in <cell line: 1>() ----> 1 training_args = TrainingArguments( 2 output_dir='./results', # output 저장 directory 3 num_train_epochs=2, # total number of training epochs 4 per_device_train_batch_size=8, # batch size per device during training 5 per_device_eval_batch_size=16, # batch size per device during evaluation 4 frames/usr/local/lib/python3.10/dist-packages/transformers/training_args.py in _setup_devices(self) 1903 if not is_sagemaker_mp_enabled(): 1904 if not is_accelerate_available(): -> 1905 raise ImportError( 1906 f"Using the `Trainer` with `PyTorch` requires `accelerate>={ACCELERATE_MIN_VERSION}`: " 1907 "Please run `pip install transformers[torch]` or `pip install accelerate -U`" ImportError: Using the `Trainer` with `PyTorch` requires `accelerate>=0.21.0`: Please run `pip install transformers[torch]` or `pip install accelerate -U`
-
해결됨딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)
201_classify_text_with_bert_tfhub_Kor.ipynb 오류
안녕하세요?201_classify_text_with_bert_tfhub_Kor.ipynb 소스 수행 시 아래와 같은 오류가 납니다.구글 colab gpu에서 돌리고 있습니다. (오류 이미지도 같이 첨부합니다.)왜 오류가 나는지 답변 부탁 드립니다. ValueError Traceback (most recent call last) <ipython-input-17-3b4b1d94b15e> in <cell line: 1>() ----> 1 classifier_model = build_classifier_model() 2 bert_raw_result = classifier_model(tf.constant(text_test)) 3 4 print(bert_raw_result) 5 print(tf.sigmoid(bert_raw_result)) 7 frames/usr/local/lib/python3.10/dist-packages/keras/src/backend/common/keras_tensor.py in __array__(self) 59 60 def __array__(self): ---> 61 raise ValueError( 62 "A KerasTensor is symbolic: it's a placeholder for a shape " 63 "an a dtype. It doesn't have any actual numerical value. " ValueError: Exception encountered when calling layer 'preprocessing' (type KerasLayer). A KerasTensor is symbolic: it's a placeholder for a shape an a dtype. It doesn't have any actual numerical value. You cannot convert it to a NumPy array. Call arguments received by layer 'preprocessing' (type KerasLayer): • inputs=<KerasTensor shape=(None,), dtype=string, sparse=None, name=text> • training=None
-
해결됨딥러닝 이론 + PyTorch 실무 완전 정복
2-8 fully connected NN answer 코드 중 torch.nn.Linear 질문드립니다!
안녕하세요. 강의 잘 듣고있습니다 :D아래 코드에서 torch.nn.Linear에 해당하는 부분이 강의서 말씀해주신 aggregation에 해당되는 부분일까요? 편의상 bias 벡터는 생략된걸까요..? class Model(torch.nn.Module) : def __init__(self) : super(Model, self).__init__() self.layers = torch.nn.Sequential( # 첫번째 레이어 torch.nn.Linear(in_features = 128, out_features = 64, bias = True), # 첫번째 레이어의 activation 함수 torch.nn.Tanh(), # 두번째 레이어 torch.nn.Linear(in_features = 64, out_features = 16, bias = True), # 두번째 레이어의 activation 함수 torch.nn.Tanh(), # 세번째 레이어 torch.nn.Linear(in_features = 16, out_features = 1, bias = True), # 세번째 레이어의 activation 함수 torch.nn.Sigmoid() ) def forward (self, x) : return self.layers(x)
-
해결됨딥러닝 이론 + PyTorch 실무 완전 정복
ToTensor와 DataLoader관련질문드립니다!
안녕하세요! 이론적 이해가 아직까지는 잘되나 코드에서 잘 이해가 가지않는 부분이 있어 질문드립니다~ToTensor에서 왜 0~255를 0~1값으로 스케일링 하는 이유는 무엇인가요?DataLoader 에서 데이터를 미니배치로 넘기면 가로,세로 길이가 32로 바뀌는 이유는 무엇인가요? squeeze 함수를 찾아보니 길이가 1인 차원이 없는 행 백터, 열백터, 스칼라 배열을 삭제한다고 하는데, 아래에서 사용되는 이유는 무엇인가요?train_features, train_labels = next(iter(train_dataloader)) # train_features.size()는 64개로 세분화된 미니배치 크기, 채널, 가로, 세로 길이를 보여준다. print("Feature batch shape : {}".format(train_features.size())) # train_labels.size()도 미니배치 크기만큼 있는 것을 확인할 수 있다. print("Labels batch shape : {}".format(train_labels.size())) img = train_features[0].squeeze() # squeeze() 길이가 1인 차원이 없는 행 백터, 열백터, 스칼라 배열을 삭제한다. label = train_labels[0] plt.imshow(img.permute(1,2,0)) plt.show print("Label : {}".format(labels_map[label.item()]))
-
미해결딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)
트랜스포머 실습 파일 실행 시 에러가 발생합니다.
130_Transformer.ipynb를 코랩 환경에서 실행하는데 25번째 코드 셸을 실행하면 에러가 발생합니다.위의 모든 코드 셸을 실행한 뒤에 다음 코드를 실행하면 ValueError: Exception encountered when calling PositionalEmbedding.call().Invalid dtype: <property object at 0x7d6f6aff73d0> Arguments received by PositionalEmbedding.call(): • x=tf.Tensor(shape=(64, 110), dtype=int64) 이런 에러가 발생합니다. 어디가 문제이며 어떻게 해결을 해야 할까요? # 포르투갈어와 영어를 위한 위치 인코딩 임베딩 레이어 생성 embed_pt = PositionalEmbedding(vocab_size=tokenizers.pt.get_vocab_size(), d_model=512) embed_en = PositionalEmbedding(vocab_size=tokenizers.en.get_vocab_size(), d_model=512) # 포르투갈어 입력에 대한 임베딩 적용 pt_emb = embed_pt(pt) # 영어 입력에 대한 임베딩 적용 en_emb = embed_en(en)
-
미해결[무료]텍스톰 TEXTOM 24 신버전 기초 강의: 빅데이터 논문 작성을 위한 SNS 인식 분석
연결중심성 정도가요...
연결중심성정도가요... 0.0974359 이렇게 나와도 괜찮은것인가요? 논문에서 보면 보통 연결 중심성이 2,270 이정도로 나오는 것 같아서요..
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
Custom Agent executor error
else: print("TOOL NAME : ", output.tool) print("TOOL INPUT : ", output.tool_input) Traceback (most recent call last): File "/Users/chaejinjeong/Desktop/myGit/Study/langchain/inflearn/5.Agent/basic.py", line 75, in <module> print("TOOL NAME : ", output.tool)output : [OpenAIToolAgentAction(tool='get_word_length', tool_input={'word': 'eudca'}, log="\nInvoking: `get_word_length` with `{'word': 'eudca'}`\n\n\n", message_log=[AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_DlTa5qRanu9HhiWGneMz2V3C', 'function': {'arguments': '{"word":"eudca"}', 'name': 'get_word_length'}, 'type': 'function'}]})], tool_call_id='call_DlTa5qRanu9HhiWGneMz2V3C')], <class 'list'>output.tool 이라는 속성이 없어서 print 해보니 AgentAction List 형태로 출력이 되었습니다.intermediate_steps = [] final_result = dict() while True: query.update({"intermediate_steps": intermediate_steps}) output: Union[AgentFinish, AgentAction] = agent.invoke(query) if isinstance(output, AgentFinish): final_result = output.return_values final_result = final_result.get("output") break else: if isinstance(output, list): output = output[0] print("TOOL NAME : ", output.tool) print("TOOL INPUT : ", output.tool_input) _tool = tools.get(output.tool) observation = _tool.run(output.tool_input) intermediate_steps.append((output, observation)) TOOL NAME : get_word_length TOOL INPUT : {'word': 'eudca'}위처럼 인덱스 0으로 접근해서 처리해야할 것 같아 글 남깁니다.
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
summary buffer memory token_limit 질문
token_limit 은 대화의 input, output set 개수 일까요 ?
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
[공유] SQLDatabase를 에디터에서 인식하지 못한다면
from langchain_community.utilities import SQLDatabasefrom langchain_community.utilities.sql_database import SQLDatabasevscode 에서 extension이 SQLDatabase를 코드를 수행할때는 상관없는데, 에디터상에서 인지못하는 문제가 있었어요 그런데 sql_database라는 패키지명까지 붙이니 해결되었습니다
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
ChatPromptTemplate.from_messages(("ai", ...)) 질문
ChatPromptTemplate.from_messages(("ai", ...))에서 system과 human은 Context와 Role을 주는 역할인지 알겠는데 ai는 어떤 역할인가요 ?
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
chroma db import 가 업데이트된 것 같습니다.
from langchain_community.vectorstores.chroma import Chroma이렇게 되어야 Chroma를 vscode에서 인식하는 것 같습니다.
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
CommonList output이 안되는데 무엇이 문제일까요 ?
from langchain.output_parsers import CommaSeparatedListOutputParserfrom langchain.prompts import PromptTemplate output_parser = CommaSeparatedListOutputParser() format_instructions = output_parser.get_format_instructions()print(f"instruction : {format_instructions}")# instruction : Your response should be a list of comma separated values, eg: `foo, bar, baz` prompt = PromptTemplate( template="List five {subject}.\n{format_instructions}", input_variables=["subject"], partial_variables={"format_instructions": format_instructions},) from langchain_openai import OpenAI llm = OpenAI(temperature=0) _input = prompt.format(subject="ice create flavors")output = llm.invoke(_input) print(output_parser.parse(output)) # ['1. Vanilla\n2. Chocolate\n3. Strawberry\n4. Mint\n5. Coffee']이렇게 작성했는데, Output이 ['1. Vanilla\n2. Chocolate\n3. Strawberry\n4. Mint\n5. Coffee'] 이렇게 나옵니다.. parser의 문제일까요 모델의 문제일까요 ?
-
해결됨실리콘밸리 엔지니어와 함께하는 랭체인(LangChain)
Langchain version이 업데이트 되어서 코드를 수정해야할 것 같습니다.
from langchain_openai import OpenAI llm = OpenAI(model="davinci-002")OpenAI 라이브러리 import 하는 방식과text-devinci-003 모델이 이제 서비스를 안하는 것 같습니다.위처럼하고 몇번 수행하니 같은 결과가 나왔습니다.
-
해결됨딥러닝 이론 + PyTorch 실무 완전 정복
13 표준화에 관한 질문
1.위의 그림에서 weight가 정규분포(Gaussian distribution)를 따르기 때문에 각 layer의 input의 분포도 정규분포를 따른다고 말씀해주셨는데 그 이유가 궁금합니다..2.표준화(Z~N(0,1))를 위해서는 확률분포가 정규분포여야 한다고 알고 있습니다..그래서 batch normalization의 위의 식에서 x가 정규분포를 가져야 한다고 생각했는데 학습 데이터셋은 직접 정규분포를 가지게 넣는다고 가정하더라도 그 다음에 있는 convolutional layer의 weight가 gradient descent에 의해 업데이트 되어 더이상 정규분포를 따르지 않으면 출력값이 정규분포를 따르지 않을수도 있지 않을까요...?
-
해결됨딥러닝 이론 + PyTorch 실무 완전 정복
Jupyter Notebook환경 관련 질문
9강 [실습] PyTorch 기초 - Tensor 강의에서 질문 있습니다.Lesson/inflearn_practicals 폴더에 아무 파일도 들어있지 않은데, 폴더가 원래 구성이 되어 있는 것이 아니고 파일을 직접 다운로드해서 폴더를 알아서 구성하는건가요?Jupyter notebook 상에서 강사님처럼 section이 모두 뜨지 않아 질문 드립니다.
-
미해결딥러닝을 활용한 자연어 처리 (NLP) 과정 (기초부터 ChatGPT/생성 모델까지)
인공지능을 활용한 앱을 만들때 어떤 언어를 쓰나요?
주제와는 직접적인 질문은 아닙니다만 물어볼 곳이 없어서 선생님께 질문드립니다. 인공지능 엔진을 이용한 어플을 만들려고 하는데, 주로 사용하는 언어가 무언가요? 파이썬, 플러터 사이에서 고민하고 있는데 이 참에 현업에서 사용하는 (프론트엔드) 언어들에 대해 폭넓게 알고 싶습니다. 감사합니다.