01/10/2018, 16:25

Có lệnh nào thoát ra khỏi hàm ngay lập tức trong python ngoài lệnh break với exit()

Mình đang làm nhận dạng giọng nói với PocketSphin vấn đề ở đây khi mình nói từ nóng nó nghe đúng chính xác từ và khi đó dòng lệnh sẽ đứng im đợi mình tạo ra một tiếng động nó mới thực hiện câu lệnh tiếp theo,
mình dùng thử lệnh break; hay thiết lập true,false nếu điểu không khắc phục,
mình muốn hỏi có lệnh nào thoát ra khỏi hàm ngay lập tức không

phamvandung viết 18:35 ngày 01/10/2018

return

Vĩ Huỳnh viết 18:39 ngày 01/10/2018

Không được bạn ơi mình thử rùi

HK boy viết 18:31 ngày 01/10/2018

Code bạn đâu rồi? Bạn có demo không?

Quân viết 18:31 ngày 01/10/2018

Bạn nên post code lên, tôn trọng người khác một chút, đừng để MN phải đoán bạn đang làm gì

Vĩ Huỳnh viết 18:26 ngày 01/10/2018

Thật sự vấn đề của mình ở đây là do nhà thiết kế người ta quy ước như vậy chứ không phải do code của mình, mình chỉ muốn hỏi có cách nào thoát ra khởi hàm ngay lặp tức ko dù câu lệnh trên nó còn thực hiện

Vĩ Huỳnh viết 18:40 ngày 01/10/2018

Không phải mình thiếu tôn trọng các bạn
Thật sự vấn đề của mình ở đây là do nhà thiết kế người ta quy ước như vậy chứ không phải do lỗi code của mình, mình chỉ muốn hỏi có cách nào thoát ra khởi hàm ngay lặp tức ko dù câu lệnh trên nó còn thực hiện

Quân viết 18:28 ngày 01/10/2018

Sao bạn vòng vo thế nhỉ, không mô tả bằng lời của bạn vì bạn có mô tả thì cũng không ai hiểu chính xác vấn đề của bạn và bạn đang sai ở đâu, nhiều khi chỗ bạn cho là không ảnh hưởng lại chính là điểm mấu chốt để sửa.
Ps: No code no help

Vĩ Huỳnh viết 18:36 ngày 01/10/2018
import pyaudio;import wave;import pydub
import os
class pocketSphinx():#Thư viện pocketsphin
	def __init__(self):
		MODELDIR = "C:\\sphinx\\pocketsphinx\\model\\en-us"
		# Create a decoder with certain model
		config = Decoder.default_config()
		config.set_string('-hmm', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\en-us\\'))
		config.set_string('-lm', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\en-us.lm.bin'))
		config.set_string('-dict', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\cmudict-en-us.dict'))
		config.set_string('-keyphrase', 'no')
		config.set_float('-kws_threshold', 1e+20)
		decoder = Decoder(config)
		audio = pyaudio.PyAudio()
		stream = audio.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
		stream.start_stream()
		result = None
		in_speech_bf = False
		decoder.start_utt()
		while True:
			buf = stream.read(1024)
			if buf:
				decoder.process_raw(buf, False, False)
				if decoder.get_in_speech() != in_speech_bf:
					in_speech_bf = decoder.get_in_speech()
					if not in_speech_bf:
						decoder.end_utt()
						print('RESULT:----------------------------------------------------------------------------------------------------------->', decoder.hyp().hypstr)
						result = decoder.hyp().hypstr
						decoder.start_utt()
					elif "no" in str(result) or "oh" in str(result) :
						return
			else:
				break;
		decoder.end_utt()

Đây mình nói chữ ’ no’ nó xác nhận đúng , nhưng nó sẽ không thực hiện lệnh kế tiếp mà nó sẽ đợi tạo ra tiếng động khác nó mới thực hiện

Quân viết 18:25 ngày 01/10/2018

mình lại thấy hoàn toàn do lỗi logic của bạn dẫn đến kết quả mà bạn không mong muốn. Mình sẽ phân tích cho bạn thấy chỗ bất hợp lí của của code bạn, bạn có thể tự mày mò tìm ra cách sửa 1 cách dễ dàng. Mình chưa làm việc với thằng này nhưng mình có kinh nghiệm làm việc với 1 số engine ASR khác, hi vọng các gợi ý của mình có thể giúp ích cho bạn
Quay trở lại code của bạn

if not in_speech_bf:
        decoder.end_utt()
        print('RESULT:------------------------------------------------------------>', decoder.hyp().hypstr)
        result = decoder.hyp().hypstr
        decoder.start_utt()
elif "no" in str(result) or "oh" in str(result):
        print('Stop')
        return

Mình đoán đoạn code dưới đây là 1 cặp để nhận diện tín hiệu giọng nói thành 1 câu hoàn chỉnh có độ tin cậy đủ lớn. Hay nói cách khác là đã nhận diện thành công audio ra text cho bạn.

decoder.start_utt()
.....
if not in_speech_bf:
        decoder.end_utt()
        print('RESULT:------------------------------------------------------------>', decoder.hyp().hypstr)
        result = decoder.hyp().hypstr

Mình không rõ ý định của bạn là gì mà lại có đoạn code dưới đây ngay sau đó.

    decoder.start_utt()
elif "no" in str(result) or "oh" in str(result) :
    return

Theo quan điểm của mình thì bạn lưu lại kết quả ở lần nhận diện hiện tại bằng dòng lệnh result = decoder.hyp().hypstr
sau đó không xử lí gì cả mà lại start 1 session nhận diện mới và xử lí kết quả nhận diện ở run loop tiếp theo. Và tất nhiên sẽ xảy ra độ trễ giữa khi print ở run loop trước và khi kết thúc khỏi vòng lặp do thư viện và pyaudio gây ra rồi

Tâm Ninja viết 18:25 ngày 01/10/2018

Đặt vấn đề

Bạn copy code của bác dưới này rồi thêm code vào àh?

stackoverflow.com
Krishna Agarwal

Python pocketsphinx recognition from the microphone

python-2.7, speech-recognition, redhat
asked by Krishna Agarwal on 09:16PM - 06 Aug 16

Có 1 vấn đề là bạn khá bảo thủ trong việc hỏi người khác dẫn đến mọi người sẽ dễ cảm thấy khó chịu khi bị hỏi. Mình nghĩ bạn nên cải thiện trong tương lai. Bởi vì nếu không có đủ dữ kiện, thì khó ai giúp đỡ được bạn. Không nên giả định là người khác phải biết hết những gì bạn biết (ở đây là tự đoán xem bạn đã làm gì).

Điều tra

Mình chưa có kinh nghiệm chạy qua đoạn code này. Cộng với thư viện này không có docs à? Mình tìm mãi không ra cay vãi. Tuy nhiên mình có thể nhận định như sau từ đoạn code gốc.

 1    import pyaudio;import wave;import pydub
 2    import os
 3    class pocketSphinx():#Thư viện pocketsphin
 4    	def __init__(self):
 5    		MODELDIR = "C:\\sphinx\\pocketsphinx\\model\\en-us"
 6    		# Create a decoder with certain model
 7    		config = Decoder.default_config()
 8    		config.set_string('-hmm', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\en-us\\'))
 9    		config.set_string('-lm', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\en-us.lm.bin'))
10    		config.set_string('-dict', os.path.join(MODELDIR, 'C:\\sphinx\\pocketsphinx\\model\\en-us\\cmudict-en-us.dict'))
11    		config.set_string('-keyphrase', 'no')
12    		config.set_float('-kws_threshold', 1e+20)
13    		decoder = Decoder(config)
14    		audio = pyaudio.PyAudio()
15    		stream = audio.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
16    		stream.start_stream()
17    		result = None
18    		in_speech_bf = False
19    		decoder.start_utt()
20    		while True:
21    			buf = stream.read(1024)
22    			if buf:
23    				decoder.process_raw(buf, False, False)
24    				if decoder.get_in_speech() != in_speech_bf:
25    					in_speech_bf = decoder.get_in_speech()
26    					if not in_speech_bf:
27    						decoder.end_utt()
28    						print('RESULT:----------------------------------------------------------------------------------------------------------->', decoder.hyp().hypstr)
29    						result = decoder.hyp().hypstr
30    						decoder.start_utt()
31    					elif "no" in str(result) or "oh" in str(result) :
32    						return
33    			else:
34    				break;
35    		decoder.end_utt()

Trong dòng số 24, mình giả định ý hiểu của mình là hàm này check xem người ta có đang nói hay là không. Nếu trạng thái ban đâu tiên là False chuyển qua True tức là bắt đầu nói thì cập nhật trạng thái mới.
Kế tiếp, cứ mỗi lần người dùng thay đổi trạng thái là nói hoặc ngừng nói thì tiến hành vào xử lý. (Nghĩa là chỉ xử lý khi có sự thay đổi trạng thái)
Trong xử lý làm như sau:
・Nếu in_speech_bf == False thì có nghĩa là họ vừa nói xong. (Sẽ không thể là cái False mặc định đầu tiên do ràng buộc ở dòng 24) Thì sẽ lấy ra kết quả và lắng nghe.
・Trong lần nói đầu tiên, code sẽ không chạy qua xử lí ở dòng 31 do lần thay đổi trạng thái thứ nhất thì result chưa có gì. Lần thay đổi trạng thái thứ hai có được result thì in_speech_bf == False.
・Lần nói tiếp theo, khi người dùng bắt đầu nói, một lần nữa trạng thái thay đổi và dòng 24 thoả mãn, code chạy đến dòng 26 thì in_speech_bf == True dẫn đến code của bạn được xử lý.

Tóm gọn là như sau

  1. Phủ định việc người dùng bắt đầu nói bằng cài đặt ở dòng 18.
  2. Chạy và kiểm tra người dùng bắt đầu nói hay chưa ở dòng 24.
  3. Kiểm tra dòng 24 nếu người dùng bắt đầu nói thì cập nhật ở dòng 25. Vì lúc này trạng thái ngược của FalseTrue nên dòng 26 bị bỏ qua và dòng 31 thì dữ liệu của result là rỗng.
  4. Kiểm tra dòng 24 nếu người dùng ngừng nói thì tiếp tục cập nhật dòng 25. Xử lý dòng 26 trả về True nên result được update. Dòng 31 bị bỏ qua do dòng 26 đã chạy.
  5. Kiểm tra dòng 24 nếu người dùng nói lần 2 thì cập nhật ở dòng 25. Dòng 26 bị bỏ qua, dòng 31 trả về giá trị dựa trên lần nói trước.

Vậy, code của bạn đã làm cho bạn phải nói thêm thì chương trình mới ngừng đúng như mô tả của bạn.

Đây mình nói chữ ’ no’ nó xác nhận đúng , nhưng nó sẽ không thực hiện lệnh kế tiếp mà nó sẽ đợi tạo ra tiếng động khác nó mới thực hiện

Nếu điều này đúng, thì chính là do code của bạn lỗi rồi. Bạn đẩy code lên từ đầu và viết ra những gì bạn đã nghiên cứu được thì bọn mình đỡ vất vả bao nhiêu.

Giải pháp:

Cách thứ nhất:

24    				if decoder.get_in_speech() != in_speech_bf:
25    					in_speech_bf = decoder.get_in_speech()
26    					if not in_speech_bf:
27    						decoder.end_utt()
28    						print('RESULT:----------------------------------------------------------------------------------------------------------->', decoder.hyp().hypstr)
29    						result = decoder.hyp().hypstr
30
31    						decoder.start_utt()
32    					if "no" in str(result) or "oh" in str(result) :
33    						return

Cách thứ hai:

24    				if decoder.get_in_speech() != in_speech_bf:
25    					in_speech_bf = decoder.get_in_speech()
26    					if not in_speech_bf:
27    						decoder.end_utt()
28    						print('RESULT:----------------------------------------------------------------------------------------------------------->', decoder.hyp().hypstr)
29    						result = decoder.hyp().hypstr
30    						if "no" in str(result) or "oh" in str(result) : 
31    							return
32    						else
33    							decoder.start_utt()

Mình viết dài như vậy để cho bạn thấy là, lần tới nên thực hiện yêu cầu của người được hỏi nếu bạn thực sự muốn nhận được câu trả lời.

Tâm Ninja viết 18:34 ngày 01/10/2018

Thêm nữa. Bạn gặp vấn đề này là do chưa hiểu được logic của đoạn code do chính bản thân viết ra. Vậy nên, khi chưa thể cảm thấy quen thuộc với syntax của Python hoặc chưa quen với việc debug bằng mắt thì bạn nên thử tìm hiểu cách debug bằng debug tool hoặc thông qua log cho quen trước đã.

Vĩ Huỳnh viết 18:32 ngày 01/10/2018

Cảm ơn bạn đã giúp đỡ, xin lỗi vì đã thiếu tôn trọng các bạn

Vĩ Huỳnh viết 18:39 ngày 01/10/2018

Cảm ơn bạn, mình xin lôi vì đã đưa thiếu dữ liệu

Bài liên quan
0